ReactOS  0.4.13-dev-73-gcfe54aa
comm.c
Go to the documentation of this file.
1 /* Unit test suite for comm functions
2  *
3  * Copyright 2003 Kevin Groeneveld
4  * Copyright 2005 Uwe Bonnes
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <stdio.h>
22 
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include "wine/test.h"
26 #include "winternl.h"
27 #include "winbase.h"
28 #include "winnls.h"
29 
30 #define TIMEOUT 1000 /* one second for Timeouts*/
31 #define SLOWBAUD 150
32 #define FASTBAUD 115200
33 #define TIMEDELTA 150 /* 150 ms uncertainty allowed */
34 
35 /* Define the appropriate LOOPBACK(s) TRUE if you have a Loopback cable with
36  * the mentioned shorts connected to your Serial port
37  */
38 #define LOOPBACK_TXD_RXD FALSE /* Sub-D 9: Short 2-3 */
39 #define LOOPBACK_CTS_RTS FALSE /* Sub-D 9: Short 7-8 */
40 #define LOOPBACK_DTR_DSR FALSE /* Sub-D 9: Short 4-6 */
41 #define LOOPBACK_DTR_RING FALSE /* Sub-D 9: Short 4-9 */
42 #define LOOPBACK_DTR_DCD FALSE /* Sub-D 9: Short 4-1 */
43 /* Many Linux serial drivers have the TIOCM_LOOP flag in the TIOCM_SET ioctl
44  * available. For the 8250 this is equivalent to TXD->RXD, OUT2->DCD,
45  * OUT1->RI, RTS->CTS and DTR->DSR
46  */
47 /* use variables and not #define to compile the code */
53 
54 static NTSTATUS (WINAPI *pNtReadFile)(HANDLE hFile, HANDLE hEvent,
58 static NTSTATUS (WINAPI *pNtWriteFile)(HANDLE hFile, HANDLE hEvent,
61  const void* buffer, ULONG length,
63 
64 typedef struct
65 {
66  char string[100];
69  DCB dcb1, dcb2;
70  COMMTIMEOUTS timeouts1, timeouts2;
71 } TEST;
72 
73 static const TEST test[] =
74 {
75  {
76  "baud=9600 parity=e data=5 stop=1 xon=on odsr=off octs=off dtr=on rts=on idsr=on",
77  TRUE, FALSE,
78  { 0x00000000, 0x00002580, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
79  { 0xffffffff, 0x00002580, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x05, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
80  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
81  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
82  },
83  {
84  "baud=0 parity=M data=6 stop=1.5 xon=off odsr=on octs=ON dtr=off rts=off idsr=OFF",
85  TRUE, FALSE,
86  { 0x00000000, 0x00000000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
87  { 0xffffffff, 0x00000000, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x06, 0x03, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
88  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
89  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
90  },
91  {
92  "BAUD=4000000000 parity=n data=7 stop=2 to=off",
93  TRUE, FALSE,
94  { 0x00000000, 0xee6b2800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
95  { 0xffffffff, 0xee6b2800, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x07, 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
96  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
97  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
98  },
99  {
100  "Baud=115200 Parity=O Data=8 To=On",
101  TRUE, FALSE,
102  { 0x00000000, 0x0001c200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
103  { 0xffffffff, 0x0001c200, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x08, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
104  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000EA60 },
105  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000EA60 }
106  },
107  {
108  "PaRiTy=s Data=7 DTR=on",
109  TRUE, FALSE,
110  { 0x00000000, 0x00000000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
111  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x07, 0x04, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
112  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
113  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
114  },
115  {
116  "data=4",
117  FALSE, FALSE,
118  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
119  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
120  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
121  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
122  },
123  {
124  "data=9",
125  FALSE, FALSE,
126  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
127  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
128  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
129  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
130  },
131  {
132  "parity=no",
133  FALSE, FALSE,
134  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
135  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
136  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
137  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
138  },
139  {
140  "stop=0",
141  FALSE, FALSE,
142  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
143  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
144  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
145  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
146  },
147  {
148  "stop=1.501",
149  FALSE, FALSE,
150  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
151  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
152  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
153  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
154  },
155  {
156  "stop=3",
157  FALSE, FALSE,
158  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
159  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
160  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
161  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
162  },
163  {
164  "to=foobar",
165  FALSE, FALSE,
166  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
167  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
168  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
169  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
170  },
171  {
172  " baud=9600",
173  FALSE, FALSE,
174  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
175  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
176  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
177  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
178  },
179  {
180  "baud= 9600",
181  FALSE, FALSE,
182  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
183  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
184  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
185  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
186  },
187  {
188  "baud=9600,data=8",
189  FALSE, FALSE,
190  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
191  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
192  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
193  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
194  },
195  {
196  "11,n,8,1",
197  TRUE, TRUE,
198  { 0x00000000, 0x0000006e, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
199  { 0xffffffff, 0x0000006e, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
200  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
201  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
202  },
203  {
204  "30 ,E, 5,1.5",
205  TRUE, TRUE,
206  { 0x00000000, 0x0000012c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x05, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
207  { 0xffffffff, 0x0000012c, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x05, 0x02, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
208  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
209  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
210  },
211  {
212  "60, m, 6, 2 ",
213  TRUE, TRUE,
214  { 0x00000000, 0x00000258, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x06, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
215  { 0xffffffff, 0x00000258, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x06, 0x03, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
216  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
217  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
218  },
219  {
220  "12 , o , 7 , 1",
221  TRUE, TRUE,
222  { 0x00000000, 0x000004b0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
223  { 0xffffffff, 0x000004b0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x07, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
224  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
225  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
226  },
227  {
228  "24,s,8,1.5",
229  TRUE, TRUE,
230  { 0x00000000, 0x00000960, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x08, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
231  { 0xffffffff, 0x00000960, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x08, 0x04, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
232  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
233  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
234  },
235  {
236  "48,n,8,1,p",
237  TRUE, TRUE,
238  { 0x00000000, 0x000012c0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
239  { 0xffffffff, 0x000012c0, 1, 1, 1, 1, 2, 1, 1, 0, 0, 1, 1, 2, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
240  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
241  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
242  },
243  {
244  "96,N,8,1 , x ",
245  TRUE, TRUE,
246  { 0x00000000, 0x00002580, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
247  { 0xffffffff, 0x00002580, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
248  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
249  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
250  },
251  {
252  "19, e, 7, 1, x",
253  TRUE, TRUE,
254  { 0x00000000, 0x00004b00, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
255  { 0xffffffff, 0x00004b00, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x07, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
256  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
257  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
258  },
259  {
260  "0,M,7,1,P",
261  TRUE, TRUE,
262  { 0x00000000, 0x00000000, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
263  { 0xffffffff, 0x00000000, 1, 1, 1, 1, 2, 1, 1, 0, 0, 1, 1, 2, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x07, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
264  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
265  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
266  },
267  {
268  "4000000000,O,7,1.5,X",
269  TRUE, TRUE,
270  { 0x00000000, 0xee6b2800, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
271  { 0xffffffff, 0xee6b2800, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x07, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
272  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
273  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
274  },
275  {
276  "96,N,8,1 to=on",
277  FALSE, TRUE,
278  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
279  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
280  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
281  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
282  },
283  {
284  "96,NO,8,1",
285  FALSE, TRUE,
286  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
287  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
288  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
289  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
290  },
291  {
292  "96,N,4,1",
293  FALSE, TRUE,
294  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
295  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
296  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
297  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
298  },
299  {
300  "96,N,9,1",
301  FALSE, TRUE,
302  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
303  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
304  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
305  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
306  },
307  {
308  "96,N,8,0",
309  FALSE, TRUE,
310  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
311  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
312  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
313  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
314  },
315  {
316  "96,N,8,3",
317  FALSE, TRUE,
318  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
319  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
320  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
321  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
322  },
323  {
324  "96,N,8,1,K",
325  FALSE, TRUE,
326  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
327  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
328  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
329  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
330  },
331  {
332  "COM0:baud=115200",
333  FALSE, FALSE,
334  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
335  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
336  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
337  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
338  },
339  {
340  "COMx:baud=38400 data=8",
341  TRUE, FALSE,
342  { 0x00000000, 0x00009600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
343  { 0xffffffff, 0x00009600, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x08, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
344  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
345  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
346  },
347  {
348  "COMx :to=on stop=1.5",
349  TRUE, FALSE,
350  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
351  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
352  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000EA60 },
353  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000EA60 }
354  },
355  {
356  "COMx: baud=12345 data=7",
357  TRUE, FALSE,
358  { 0x00000000, 0x00003039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
359  { 0xffffffff, 0x00003039, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x07, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
360  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
361  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
362  },
363  {
364  "COMx : xon=on odsr=off",
365  TRUE, FALSE,
366  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
367  { 0xffffffff, 0xffffffff, 1, 1, 1, 0, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
368  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
369  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
370  },
371  {
372  "COM0:9600,N,8,1",
373  FALSE, TRUE,
374  { 0x00000000, 0x00000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
375  { 0xffffffff, 0xffffffff, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
376  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
377  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
378  },
379  {
380  "COMx:9600,N,8,1",
381  TRUE, TRUE,
382  { 0x00000000, 0x00002580, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
383  { 0xffffffff, 0x00002580, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
384  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
385  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
386  },
387  {
388  "COMx: 11,E,7,2",
389  TRUE, TRUE,
390  { 0x00000000, 0x0000006e, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x07, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
391  { 0xffffffff, 0x0000006e, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x07, 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
392  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
393  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
394  },
395  {
396  "COMx :19,M,5,1",
397  TRUE, TRUE,
398  { 0x00000000, 0x00004b00, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
399  { 0xffffffff, 0x00004b00, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x05, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
400  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
401  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
402  },
403  {
404  "COMx : 57600,S,6,2,x",
405  TRUE, TRUE,
406  { 0x00000000, 0x0000e100, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0x00000, 0x0000, 0x0000, 0x0000, 0x06, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0000 },
407  { 0xffffffff, 0x0000e100, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0x1ffff, 0xffff, 0xffff, 0xffff, 0x06, 0x04, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffff },
408  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
409  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
410  },
411 };
412 
413 #define TEST_COUNT (sizeof(test) / sizeof(TEST))
414 
415 /* This function can be useful if you are modifying the test cases and want to
416  output the contents of a DCB structure. */
417 /*static print_dcb(DCB *pdcb)
418 {
419  printf("0x%08x, 0x%08x, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, 0x%05x, 0x%04x, 0x%04x, 0x%04x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%04x\n",
420  pdcb->DCBlength,
421  pdcb->BaudRate,
422  pdcb->fBinary,
423  pdcb->fParity,
424  pdcb->fOutxCtsFlow,
425  pdcb->fOutxDsrFlow,
426  pdcb->fDtrControl,
427  pdcb->fDsrSensitivity,
428  pdcb->fTXContinueOnXoff,
429  pdcb->fOutX,
430  pdcb->fInX,
431  pdcb->fErrorChar,
432  pdcb->fNull,
433  pdcb->fRtsControl,
434  pdcb->fAbortOnError,
435  pdcb->fDummy2,
436  pdcb->wReserved,
437  pdcb->XonLim,
438  pdcb->XoffLim,
439  pdcb->ByteSize,
440  pdcb->Parity,
441  pdcb->StopBits,
442  pdcb->XonChar & 0xff,
443  pdcb->XoffChar & 0xff,
444  pdcb->ErrorChar & 0xff,
445  pdcb->EofChar & 0xff,
446  pdcb->EvtChar & 0xff,
447  pdcb->wReserved1 & 0xffff );
448 } */
449 
450 static void check_result(const char *function, const TEST *ptest, int initial_value, BOOL result)
451 {
452  DWORD LastError = GetLastError();
453  DWORD CorrectError = (ptest->result ? 0xdeadbeef : ERROR_INVALID_PARAMETER);
454 
455  ok(LastError == CorrectError, "%s(\"%s\"), 0x%02x: GetLastError() returned %d, should be %d\n", function, ptest->string, initial_value, LastError, CorrectError);
456  ok(result == ptest->result, "%s(\"%s\"), 0x%02x: return value should be %s\n", function, ptest->string, initial_value, ptest->result ? "TRUE" : "FALSE");
457 }
458 
459 #define check_dcb_member(a,b) ok(pdcb1->a == pdcb2->a, "%s(\"%s\"), 0x%02x: "#a" is "b", should be "b"\n", function, ptest->string, initial_value, pdcb1->a, pdcb2->a)
460 #define check_dcb_member2(a,c,b) if(pdcb2->a == c) { check_dcb_member(a,b); } else { ok(pdcb1->a == pdcb2->a || pdcb1->a == c, "%s(\"%s\"), 0x%02x: "#a" is "b", should be "b" or "b"\n", function, ptest->string, initial_value, pdcb1->a, pdcb2->a, c); }
461 
462 static void check_dcb(const char *function, const TEST *ptest, int initial_value, const DCB *pdcb1, const DCB *pdcb2)
463 {
464  /* DCBlength is a special case since Win 9x sets it but NT does not.
465  We will accept either as correct. */
466  check_dcb_member2(DCBlength, (DWORD)sizeof(DCB), "%u");
467 
468  /* For old style control strings Win 9x does not set the next five members, NT does. */
469  if(ptest->old_style && ptest->result)
470  {
471  check_dcb_member2(fOutxCtsFlow, ((unsigned int)initial_value & 1), "%u");
472  check_dcb_member2(fDtrControl, ((unsigned int)initial_value & 3), "%u");
473  check_dcb_member2(fOutX, ((unsigned int)initial_value & 1), "%u");
474  check_dcb_member2(fInX, ((unsigned)initial_value & 1), "%u");
475  check_dcb_member2(fRtsControl, ((unsigned)initial_value & 3), "%u");
476  }
477  else
478  {
479  check_dcb_member(fOutxCtsFlow, "%u");
480  check_dcb_member(fDtrControl, "%u");
481  check_dcb_member(fOutX, "%u");
482  check_dcb_member(fInX, "%u");
483  check_dcb_member(fRtsControl, "%u");
484  }
485 
486  if(ptest->result)
487  {
488  /* For the idsr=xxx parameter, NT sets fDsrSensitivity, 9x sets
489  fOutxDsrFlow. */
490  if(!ptest->old_style)
491  {
492  check_dcb_member2(fOutxDsrFlow, pdcb2->fDsrSensitivity, "%u");
493  check_dcb_member2(fDsrSensitivity, pdcb2->fOutxDsrFlow, "%u");
494  }
495  else
496  {
497  /* For old style control strings Win 9x does not set the
498  fOutxDsrFlow member, NT does. */
499  check_dcb_member2(fOutxDsrFlow, ((unsigned int)initial_value & 1), "%u");
500  check_dcb_member(fDsrSensitivity, "%u");
501  }
502  }
503  else
504  {
505  check_dcb_member(fOutxDsrFlow, "%u");
506  check_dcb_member(fDsrSensitivity, "%u");
507  }
508 
509  /* Check the result of the DCB members. */
510  check_dcb_member(BaudRate, "%u");
511  check_dcb_member(fBinary, "%u");
512  check_dcb_member(fParity, "%u");
513  check_dcb_member(fTXContinueOnXoff, "%u");
514  check_dcb_member(fErrorChar, "%u");
515  check_dcb_member(fNull, "%u");
516  check_dcb_member(fAbortOnError, "%u");
517  check_dcb_member(fDummy2, "%u");
518  check_dcb_member(wReserved, "%u");
519  check_dcb_member(XonLim, "%u");
520  check_dcb_member(XoffLim, "%u");
521  check_dcb_member(ByteSize, "%u");
522  check_dcb_member(Parity, "%u");
523  check_dcb_member(StopBits, "%u");
524  check_dcb_member(XonChar, "%d");
525  check_dcb_member(XoffChar, "%d");
526  check_dcb_member(ErrorChar, "%d");
527  check_dcb_member(EofChar, "%d");
528  check_dcb_member(EvtChar, "%d");
529  check_dcb_member(wReserved1, "%u");
530 }
531 
532 #define check_timeouts_member(a) ok(ptimeouts1->a == ptimeouts2->a, "%s(\"%s\"), 0x%02x: "#a" is %u, should be %u\n", function, ptest->string, initial_value, ptimeouts1->a, ptimeouts2->a);
533 
534 static void check_timeouts(const char *function, const TEST *ptest, int initial_value, const COMMTIMEOUTS *ptimeouts1, const COMMTIMEOUTS *ptimeouts2)
535 {
536  check_timeouts_member(ReadIntervalTimeout);
537  check_timeouts_member(ReadTotalTimeoutMultiplier);
538  check_timeouts_member(ReadTotalTimeoutConstant);
539  check_timeouts_member(WriteTotalTimeoutMultiplier);
540  check_timeouts_member(WriteTotalTimeoutConstant);
541 }
542 
543 static void test_BuildCommDCBA(const char *string, const TEST *ptest, int initial_value, const DCB *pexpected_dcb)
544 {
545  BOOL result;
546  DCB dcb;
547 
548  /* set initial conditions */
549  memset(&dcb, initial_value, sizeof(DCB));
550  SetLastError(0xdeadbeef);
551 
552  result = BuildCommDCBA(string, &dcb);
553 
554  /* check results */
555  check_result("BuildCommDCBA", ptest, initial_value, result);
556  check_dcb("BuildCommDCBA", ptest, initial_value, &dcb, pexpected_dcb);
557 }
558 
559 static void test_BuildCommDCBAndTimeoutsA(const char *string, const TEST *ptest, int initial_value, const DCB *pexpected_dcb, const COMMTIMEOUTS *pexpected_timeouts)
560 {
561  BOOL result;
562  DCB dcb;
564 
565  /* set initial conditions */
566  memset(&dcb, initial_value, sizeof(DCB));
567  memset(&timeouts, initial_value, sizeof(COMMTIMEOUTS));
568  SetLastError(0xdeadbeef);
569 
570  result = BuildCommDCBAndTimeoutsA(string, &dcb, &timeouts);
571 
572  /* check results */
573  check_result("BuildCommDCBAndTimeoutsA", ptest, initial_value, result);
574  check_dcb("BuildCommDCBAndTimeoutsA", ptest, initial_value, &dcb, pexpected_dcb);
575  check_timeouts("BuildCommDCBAndTimeoutsA", ptest, initial_value, &timeouts, pexpected_timeouts);
576 }
577 
578 static void test_BuildCommDCBW(const char *string, const TEST *ptest, int initial_value, const DCB *pexpected_dcb)
579 {
580  BOOL result;
581  DCB dcb;
582  WCHAR wide_string[sizeof(ptest->string)];
583  static int reportedDCBW = 0;
584 
585  MultiByteToWideChar(CP_ACP, 0, string, -1, wide_string, sizeof(wide_string) / sizeof(WCHAR));
586 
587  /* set initial conditions */
588  memset(&dcb, initial_value, sizeof(DCB));
589  SetLastError(0xdeadbeef);
590 
591  result = BuildCommDCBW(wide_string, &dcb);
592 
594  {
595  if(!reportedDCBW++)
596  win_skip("BuildCommDCBW is not implemented\n");
597  return;
598  }
599 
600  /* check results */
601  check_result("BuildCommDCBW", ptest, initial_value, result);
602  check_dcb("BuildCommDCBW", ptest, initial_value, &dcb, pexpected_dcb);
603 }
604 
605 static void test_BuildCommDCBAndTimeoutsW(const char *string, const TEST *ptest, int initial_value, const DCB *pexpected_dcb, const COMMTIMEOUTS *pexpected_timeouts)
606 {
607  BOOL result;
608  DCB dcb;
610  WCHAR wide_string[sizeof(ptest->string)];
611  static int reportedDCBAndTW = 0;
612 
613  MultiByteToWideChar(CP_ACP, 0, string, -1, wide_string, sizeof(wide_string) / sizeof(WCHAR));
614 
615  /* set initial conditions */
616  memset(&dcb, initial_value, sizeof(DCB));
617  memset(&timeouts, initial_value, sizeof(COMMTIMEOUTS));
618  SetLastError(0xdeadbeef);
619 
620  result = BuildCommDCBAndTimeoutsW(wide_string, &dcb, &timeouts);
621 
623  {
624  if(!reportedDCBAndTW++)
625  win_skip("BuildCommDCBAndTimeoutsW is not implemented\n");
626  return;
627  }
628 
629  /* check results */
630  check_result("BuildCommDCBAndTimeoutsW", ptest, initial_value, result);
631  check_dcb("BuildCommDCBAndTimeoutsW", ptest, initial_value, &dcb, pexpected_dcb);
632  check_timeouts("BuildCommDCBAndTimeoutsW", ptest, initial_value, &timeouts, pexpected_timeouts);
633 }
634 
635 static void test_BuildCommDCB(void)
636 {
637  char port_name[] = "COMx";
638  char port = 0;
639  unsigned int i;
640  char *ptr;
641 
642  /* Some of these tests require a valid COM port. This loop will try to find
643  a valid port. */
644  for(port_name[3] = '1'; port_name[3] <= '9'; port_name[3]++)
645  {
646  COMMCONFIG commconfig;
647  DWORD size = sizeof(COMMCONFIG);
648 
649  if(GetDefaultCommConfigA(port_name, &commconfig, &size))
650  {
651  port = port_name[3];
652  break;
653  }
654  }
655 
656  if(!port)
657  trace("Could not find a valid COM port. Some tests will be skipped.\n");
658 
659  for(i = 0; i < TEST_COUNT; i++)
660  {
661  char string[sizeof(test[i].string)];
662 
663  strcpy(string, test[i].string);
664 
665  /* Check if this test case needs a valid COM port. */
666  ptr = strstr(string, "COMx");
667 
668  /* If required, substitute valid port number into device control string. */
669  if(ptr)
670  {
671  if(port)
672  ptr[3] = port;
673  else
674  continue;
675  }
676 
677  test_BuildCommDCBA(string, &test[i], 0x00, &test[i].dcb1);
678  test_BuildCommDCBA(string, &test[i], 0xff, &test[i].dcb2);
679  test_BuildCommDCBAndTimeoutsA(string, &test[i], 0x00, &test[i].dcb1, &test[i].timeouts1);
680  test_BuildCommDCBAndTimeoutsA(string, &test[i], 0xff, &test[i].dcb2, &test[i].timeouts2);
681 
682  test_BuildCommDCBW(string, &test[i], 0x00, &test[i].dcb1);
683  test_BuildCommDCBW(string, &test[i], 0xff, &test[i].dcb2);
684  test_BuildCommDCBAndTimeoutsW(string, &test[i], 0x00, &test[i].dcb1, &test[i].timeouts1);
685  test_BuildCommDCBAndTimeoutsW(string, &test[i], 0xff, &test[i].dcb2, &test[i].timeouts2);
686  }
687 }
688 
689 static HANDLE test_OpenComm(BOOL doOverlap)
690 {
692  char port_name[] = "COMx";
693  static BOOL shown = FALSE;
694  DWORD errors;
695  COMSTAT comstat;
696 
697  /* Try to find a port */
698  for(port_name[3] = '1'; port_name[3] <= '9'; port_name[3]++)
699  {
700  hcom = CreateFileA( port_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
701  (doOverlap)?FILE_FLAG_OVERLAPPED:0, NULL );
702  if (hcom != INVALID_HANDLE_VALUE)
703  break;
704  }
705  if(!shown)
706  {
707  if (hcom == INVALID_HANDLE_VALUE)
708  trace("Could not find a valid COM port.\n");
709  else
710  trace("Found Com port %s. Connected devices may disturb results\n", port_name);
711  /*shown = TRUE; */
712  }
713  if (hcom != INVALID_HANDLE_VALUE)
714  {
715  BOOL ret;
716 
717  ret = ClearCommError(hcom, &errors, &comstat);
719  {
720  if (GetLastError() == ERROR_NOT_READY)
721  trace("%s doesn't respond, skipping the test\n", port_name);
722  else
723  trace("%s is not a real serial port, skipping the test\n", port_name);
724  CloseHandle(hcom);
725  return INVALID_HANDLE_VALUE;
726  }
727 
728  ok(ret, "Unexpected error %u on open\n", GetLastError());
729  ok(comstat.cbInQue == 0, "Unexpected %d chars in InQueue\n",comstat.cbInQue);
730  ok(comstat.cbOutQue == 0, "Still pending %d charcters in OutQueue\n", comstat.cbOutQue);
731  ok(errors == 0, "Unexpected errors 0x%08x\n", errors);
732  }
733  return hcom;
734 }
735 
736 static void test_GetModemStatus(HANDLE hcom)
737 {
738  DWORD ModemStat = 0;
739 
740  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
741  trace("GetCommModemStatus returned 0x%08x->%s%s%s%s\n", ModemStat,
742  (ModemStat &MS_RLSD_ON)?"MS_RLSD_ON ":"",
743  (ModemStat &MS_RING_ON)?"MS_RING_ON ":"",
744  (ModemStat &MS_DSR_ON)?"MS_DSR_ON ":"",
745  (ModemStat &MS_CTS_ON)?"MS_CTS_ON ":"");
746 }
747 
748 /* When we don't write anything, Read should time out even on a loopbacked port */
749 static void test_ReadTimeOut(void)
750 {
751  HANDLE hcom;
752  DCB dcb;
754  char rbuf[32];
755  DWORD before, after, read, timediff, LastError;
756  BOOL res;
757 
758  hcom = test_OpenComm(FALSE);
759  if (hcom == INVALID_HANDLE_VALUE) return;
760 
761  test_GetModemStatus(hcom);
762 
763  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
764  dcb.BaudRate = FASTBAUD;
765  dcb.ByteSize = 8;
766  dcb.Parity = NOPARITY;
767  dcb.fRtsControl=RTS_CONTROL_ENABLE;
768  dcb.fDtrControl=DTR_CONTROL_ENABLE;
769  dcb.StopBits = ONESTOPBIT;
770  ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
771 
772  ZeroMemory( &timeouts, sizeof(timeouts));
773  timeouts.ReadTotalTimeoutConstant = TIMEOUT;
774  ok(SetCommTimeouts(hcom, &timeouts),"SetCommTimeouts failed\n");
775 
776  before = GetTickCount();
777  SetLastError(0xdeadbeef);
778  res = ReadFile(hcom, rbuf, sizeof(rbuf), &read, NULL);
779  LastError = GetLastError();
780  after = GetTickCount();
781  ok( res == TRUE, "A timed-out read should return TRUE\n");
782  ok( LastError == 0xdeadbeef, "err=%d\n", LastError);
783  timediff = after - before;
784  ok( timediff > TIMEOUT>>2 && timediff < TIMEOUT *2,
785  "Unexpected TimeOut %d, expected %d\n", timediff, TIMEOUT);
786 
787  CloseHandle(hcom);
788 }
789 
790 static void test_waittxempty(void)
791 {
792  HANDLE hcom;
793  DCB dcb;
795  char tbuf[]="test_waittxempty";
796  DWORD before, after, bytes, timediff, evtmask, errors, i;
797  BOOL res;
798  DWORD baud = SLOWBAUD;
799  OVERLAPPED ovl_write, ovl_wait, ovl_wait2;
800  COMSTAT stat;
801 
802  hcom = test_OpenComm(TRUE);
803  if (hcom == INVALID_HANDLE_VALUE) return;
804 
805  /* set a low baud rate to have ample time*/
806  res = GetCommState(hcom, &dcb);
807  ok(res, "GetCommState error %d\n", GetLastError());
808  dcb.BaudRate = baud;
809  dcb.ByteSize = 8;
810  dcb.Parity = NOPARITY;
811  dcb.fRtsControl=RTS_CONTROL_ENABLE;
812  dcb.fDtrControl=DTR_CONTROL_ENABLE;
813  dcb.StopBits = ONESTOPBIT;
814  res = SetCommState(hcom, &dcb);
815  ok(res, "SetCommState error %d\n", GetLastError());
816 
817  ZeroMemory( &timeouts, sizeof(timeouts));
818  timeouts.ReadTotalTimeoutConstant = TIMEOUT;
819  res = SetCommTimeouts(hcom, &timeouts);
820  ok(res,"SetCommTimeouts error %d\n", GetLastError());
821 
822  res = SetupComm(hcom, 1024, 1024);
823  ok(res, "SetUpComm error %d\n", GetLastError());
824 
825  /* calling SetCommMask after WriteFile leads to WaitCommEvent failures
826  * due to timeout (no events) under testbot VMs and VirtualBox
827  */
828  res = SetCommMask(hcom, EV_TXEMPTY);
829  ok(res, "SetCommMask error %d\n", GetLastError());
830 
831  SetLastError(0xdeadbeef);
832  res = WriteFile(hcom, tbuf, sizeof(tbuf), &bytes, NULL);
833  ok(!res, "WriteFile on an overlapped handle without ovl structure should fail\n");
834  ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
835 
836  S(U(ovl_write)).Offset = 0;
837  S(U(ovl_write)).OffsetHigh = 0;
838  ovl_write.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
839  before = GetTickCount();
840  SetLastError(0xdeadbeef);
841  res = WriteFile(hcom, tbuf, sizeof(tbuf), &bytes, &ovl_write);
842  after = GetTickCount();
843  ok((!res && GetLastError() == ERROR_IO_PENDING) || (res && bytes == sizeof(tbuf)),
844  "WriteFile returned %d, written %u bytes, error %d\n", res, bytes, GetLastError());
845  if (!res) ok(!bytes, "expected 0, got %u\n", bytes);
846  ok(after - before < 30, "WriteFile took %d ms to write %d Bytes at %d Baud\n",
847  after - before, bytes, baud);
848  /* don't wait for WriteFile completion */
849 
850  S(U(ovl_wait)).Offset = 0;
851  S(U(ovl_wait)).OffsetHigh = 0;
852  ovl_wait.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
853  evtmask = 0;
854  before = GetTickCount();
855  SetLastError(0xdeadbeef);
856  res = WaitCommEvent(hcom, &evtmask, &ovl_wait);
857  ok(!res && GetLastError() == ERROR_IO_PENDING, "WaitCommEvent error %d\n", GetLastError());
858  after = GetTickCount();
859  ok(after - before < 30, "WaitCommEvent should have returned immediately, took %d ms\n", after - before);
860  res = WaitForSingleObject(ovl_wait.hEvent, 1500);
861  ok(res == WAIT_OBJECT_0, "WaitCommEvent failed with a timeout\n");
862  if (res == WAIT_OBJECT_0)
863  {
864  res = GetOverlappedResult(hcom, &ovl_wait, &bytes, FALSE);
865  ok(res, "GetOverlappedResult reported error %d\n", GetLastError());
866  ok(bytes == sizeof(evtmask), "expected %u, written %u\n", (UINT)sizeof(evtmask), bytes);
867  res = TRUE;
868  }
869  else
870  {
871  /* unblock pending wait */
872  trace("recovering after WAIT_TIMEOUT...\n");
873  res = SetCommMask(hcom, EV_TXEMPTY);
874  ok(res, "SetCommMask error %d\n", GetLastError());
875 
876  res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT);
877  ok(res == WAIT_OBJECT_0, "WaitCommEvent failed with a timeout\n");
878 
879  res = FALSE;
880  }
881  after = GetTickCount();
882  ok(res, "WaitCommEvent error %d\n", GetLastError());
883  ok(evtmask & EV_TXEMPTY, "WaitCommEvent: expected EV_TXEMPTY, got %#x\n", evtmask);
884  CloseHandle(ovl_wait.hEvent);
885 
886  timediff = after - before;
887  trace("WaitCommEvent for EV_TXEMPTY took %d ms (timeout 1500)\n", timediff);
888  ok(timediff < 1200, "WaitCommEvent used %d ms for waiting\n", timediff);
889 
890  res = WaitForSingleObject(ovl_write.hEvent, 0);
891  ok(res == WAIT_OBJECT_0, "WriteFile failed with a timeout\n");
892  res = GetOverlappedResult(hcom, &ovl_write, &bytes, FALSE);
893  ok(res, "GetOverlappedResult reported error %d\n", GetLastError());
894  ok(bytes == sizeof(tbuf), "expected %u, written %u\n", (UINT)sizeof(tbuf), bytes);
895  CloseHandle(ovl_write.hEvent);
896 
897  CloseHandle(hcom);
898 
899  for (i = 0; i < 2; i++)
900  {
901  hcom = test_OpenComm(TRUE);
902  if (hcom == INVALID_HANDLE_VALUE) return;
903 
904  res = SetCommMask(hcom, EV_TXEMPTY);
905  ok(res, "SetCommMask error %d\n", GetLastError());
906 
907  if (i == 0)
908  {
909  S(U(ovl_write)).Offset = 0;
910  S(U(ovl_write)).OffsetHigh = 0;
911  ovl_write.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
912  before = GetTickCount();
913  SetLastError(0xdeadbeef);
914  res = WriteFile(hcom, tbuf, sizeof(tbuf), &bytes, &ovl_write);
915  ok((!res && GetLastError() == ERROR_IO_PENDING) || (res && bytes == sizeof(tbuf)),
916  "WriteFile returned %d, written %u bytes, error %d\n", res, bytes, GetLastError());
917  if (!res) ok(!bytes, "expected 0, got %u\n", bytes);
918 
919  ClearCommError(hcom, &errors, &stat);
920  ok(stat.cbInQue == 0, "InQueue should be empty, got %d bytes\n", stat.cbInQue);
921  ok(stat.cbOutQue != 0 || broken(stat.cbOutQue == 0) /* VM */, "OutQueue should not be empty\n");
922  ok(errors == 0, "ClearCommErrors: Unexpected error 0x%08x\n", errors);
923 
924  res = GetOverlappedResult(hcom, &ovl_write, &bytes, TRUE);
925  ok(res, "GetOverlappedResult reported error %d\n", GetLastError());
926  ok(bytes == sizeof(tbuf), "expected %u, written %u\n", (UINT)sizeof(tbuf), bytes);
927  CloseHandle(ovl_write.hEvent);
928 
929  res = FlushFileBuffers(hcom);
930  ok(res, "FlushFileBuffers error %d\n", GetLastError());
931  }
932 
933  ClearCommError(hcom, &errors, &stat);
934  ok(stat.cbInQue == 0, "InQueue should be empty, got %d bytes\n", stat.cbInQue);
935  ok(stat.cbOutQue == 0, "OutQueue should be empty, got %d bytes\n", stat.cbOutQue);
936  ok(errors == 0, "ClearCommErrors: Unexpected error 0x%08x\n", errors);
937 
938  S(U(ovl_wait)).Offset = 0;
939  S(U(ovl_wait)).OffsetHigh = 0;
940  ovl_wait.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
941  evtmask = 0;
942  SetLastError(0xdeadbeef);
943  res = WaitCommEvent(hcom, &evtmask, &ovl_wait);
944  ok(res /* busy system */ || GetLastError() == ERROR_IO_PENDING,
945  "%d: WaitCommEvent error %d\n", i, GetLastError());
946 
947  res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT);
948  if (i == 0)
949  ok(res == WAIT_OBJECT_0, "WaitCommEvent failed with a timeout\n");
950  else
951  ok(res == WAIT_TIMEOUT, "WaitCommEvent should fail with a timeout\n");
952  if (res == WAIT_OBJECT_0)
953  {
954  res = GetOverlappedResult(hcom, &ovl_wait, &bytes, FALSE);
955  ok(res, "GetOverlappedResult reported error %d\n", GetLastError());
956  ok(bytes == sizeof(evtmask), "expected %u, written %u\n", (UINT)sizeof(evtmask), bytes);
957  ok(res, "WaitCommEvent error %d\n", GetLastError());
958  ok(evtmask & EV_TXEMPTY, "WaitCommEvent: expected EV_TXEMPTY, got %#x\n", evtmask);
959  }
960  else
961  {
962  ok(!evtmask, "WaitCommEvent: expected 0, got %#x\n", evtmask);
963 
964  S(U(ovl_wait2)).Offset = 0;
965  S(U(ovl_wait2)).OffsetHigh = 0;
966  ovl_wait2.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
967  SetLastError(0xdeadbeef);
968  res = WaitCommEvent(hcom, &evtmask, &ovl_wait2);
969  ok(!res, "WaitCommEvent should fail if there is a pending wait\n");
970  ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
971  CloseHandle(ovl_wait2.hEvent);
972 
973  /* unblock pending wait */
974  trace("recovering after WAIT_TIMEOUT...\n");
975  res = SetCommMask(hcom, EV_TXEMPTY);
976  ok(res, "SetCommMask error %d\n", GetLastError());
977 
978  res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT);
979  ok(res == WAIT_OBJECT_0, "WaitCommEvent failed with a timeout\n");
980  CloseHandle(ovl_wait.hEvent);
981  }
982 
983  CloseHandle(hcom);
984  }
985 }
986 
987 /* A new open handle should not return error or have bytes in the Queues */
988 static void test_ClearCommError(void)
989 {
990  HANDLE hcom;
991  DWORD errors;
992  COMSTAT lpStat;
993 
994  hcom = test_OpenComm(FALSE);
995  if (hcom == INVALID_HANDLE_VALUE) return;
996 
997  ok(ClearCommError(hcom, &errors, &lpStat), "ClearCommError failed\n");
998  ok(lpStat.cbInQue == 0, "Unexpected %d chars in InQueue\n", lpStat.cbInQue);
999  ok(lpStat.cbOutQue == 0, "Unexpected %d chars in OutQueue\n", lpStat.cbOutQue);
1000  ok(errors == 0, "ClearCommErrors: Unexpected error 0x%08x\n", errors);
1001 
1002  CloseHandle(hcom);
1003 }
1004 
1005 static void test_non_pending_errors(void)
1006 {
1007  HANDLE hcom;
1008  DCB dcb;
1009  DWORD err;
1010 
1011  hcom = test_OpenComm(FALSE);
1012  if (hcom == INVALID_HANDLE_VALUE) return;
1013 
1014  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1015  dcb.ByteSize = 255; /* likely bogus */
1016  ok(!SetCommState(hcom, &dcb), "SetCommState should have failed\n");
1017  ok(ClearCommError(hcom, &err, NULL), "ClearCommError should succeed\n");
1018  ok(!(err & CE_MODE), "ClearCommError shouldn't set CE_MODE byte in this case (%x)\n", err);
1019 
1020  CloseHandle(hcom);
1021 }
1022 
1023 static void test_LoopbackRead(void)
1024 {
1025  HANDLE hcom;
1026  DCB dcb;
1028  char rbuf[32];
1029  DWORD before, after, diff, read, read1, written, evtmask=0, i;
1030  BOOL res;
1031  char tbuf[]="test_LoopbackRead";
1032 
1033  if (!loopback_txd_rxd) return;
1034 
1035  hcom = test_OpenComm(FALSE);
1036  if (hcom == INVALID_HANDLE_VALUE) return;
1037 
1038  trace("Starting test_LoopbackRead\n");
1039  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1040  dcb.BaudRate = FASTBAUD;
1041  dcb.ByteSize = 8;
1042  dcb.Parity = NOPARITY;
1043  dcb.fRtsControl=RTS_CONTROL_ENABLE;
1044  dcb.fDtrControl=DTR_CONTROL_ENABLE;
1045  dcb.StopBits = ONESTOPBIT;
1046  ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
1047 
1048  ZeroMemory( &timeouts, sizeof(timeouts));
1049  timeouts.ReadTotalTimeoutConstant = TIMEOUT;
1050  ok(SetCommTimeouts(hcom, &timeouts),"SetCommTimeouts failed\n");
1051 
1052  ok(SetCommMask(hcom, EV_TXEMPTY), "SetCommMask failed\n");
1053 
1054  before = GetTickCount();
1055  ok(WriteFile(hcom,tbuf,sizeof(tbuf),&written, NULL), "WriteFile failed\n");
1056  after = GetTickCount();
1057  ok(written == sizeof(tbuf),"WriteFile %d bytes written\n", written);
1058  diff = after -before;
1059 
1060  /* make sure all bytes are written, so Readfile will succeed in one call*/
1061  ok(WaitCommEvent(hcom, &evtmask, NULL), "WaitCommEvent failed\n");
1062  before = GetTickCount();
1063  ok(evtmask == EV_TXEMPTY,
1064  "WaitCommEvent: Unexpected EvtMask 0x%08x, expected 0x%08x\n",
1065  evtmask, EV_TXEMPTY);
1066  trace("Write %d ms WaitCommEvent EV_TXEMPTY %d ms\n", diff, before- after);
1067 
1068  read=0;
1069  ok(ReadFile(hcom, rbuf, sizeof(rbuf), &read, NULL), "Readfile failed\n");
1070  ok(read == sizeof(tbuf),"ReadFile read %d bytes, expected \"%s\"\n", read,rbuf);
1071 
1072  /* Now do the same with a slower Baud rate.
1073  As we request more characters than written, we will hit the timeout
1074  */
1075 
1076  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1077  dcb.BaudRate = 9600;
1078  dcb.ByteSize = 8;
1079  dcb.Parity = NOPARITY;
1080  dcb.fRtsControl=RTS_CONTROL_ENABLE;
1081  dcb.fDtrControl=DTR_CONTROL_ENABLE;
1082  dcb.StopBits = ONESTOPBIT;
1083  ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
1084 
1085  ok(SetCommMask(hcom, EV_RXCHAR), "SetCommMask failed\n");
1086  ok(WriteFile(hcom,tbuf,sizeof(tbuf),&written, NULL), "WriteFile failed\n");
1087  ok(written == sizeof(tbuf),"WriteFile %d bytes written\n", written);
1088 
1089  trace("WaitCommEventEV_RXCHAR\n");
1090  ok(WaitCommEvent(hcom, &evtmask, NULL), "WaitCommEvent failed\n");
1091  ok(evtmask == EV_RXCHAR, "WaitCommEvent: Unexpected EvtMask 0x%08x, expected 0x%08x\n",
1092  evtmask, EV_RXCHAR);
1093 
1094  before = GetTickCount();
1095  res = ReadFile(hcom, rbuf, sizeof(rbuf), &read, NULL);
1096  after = GetTickCount();
1097  ok(res, "Readfile failed\n");
1098  ok(read == sizeof(tbuf),"ReadFile read %d bytes\n", read);
1099  diff = after - before;
1100  trace("Readfile for %d chars took %d ms\n", read, diff);
1101  ok( (diff > TIMEOUT - TIMEDELTA) && (diff < TIMEOUT + TIMEDELTA),
1102  "Timedout Wait took %d ms, expected around %d\n", diff, TIMEOUT);
1103 
1104  /* now do a plain read with slow speed
1105  * This will result in several low level reads and a timeout to happen
1106  */
1107  dcb.BaudRate = SLOWBAUD;
1108  ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
1109  ok(WriteFile(hcom,tbuf,sizeof(tbuf),&written, NULL), "WriteFile failed\n");
1110  before = GetTickCount();
1111  read = 0;
1112  read1 =0;
1113  i=0;
1114  do
1115  {
1116  res = ReadFile(hcom, rbuf+read, sizeof(rbuf)-read, &read1, NULL);
1117  ok(res, "Readfile failed\n");
1118  read += read1;
1119  i++;
1120  }
1121  while ((read < sizeof(tbuf)) && (i <10));
1122  after = GetTickCount();
1123  ok( read == sizeof(tbuf),"ReadFile read %d bytes\n", read);
1124  trace("Plain Read for %d char at %d baud took %d ms\n", read, SLOWBAUD, after-before);
1125 
1126  CloseHandle(hcom);
1127 }
1128 
1129 static void test_LoopbackCtsRts(void)
1130 {
1131  HANDLE hcom;
1132  DWORD ModemStat = 0, defaultStat = 0;
1133  DCB dcb;
1134 
1135  if (!loopback_rts_cts) return;
1136 
1137  hcom = test_OpenComm(FALSE);
1138  if (hcom == INVALID_HANDLE_VALUE) return;
1139 
1140  memset (&dcb, 0, sizeof (dcb));
1141  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1142  if (dcb.fRtsControl == RTS_CONTROL_HANDSHAKE)
1143  {
1144  trace("RTS_CONTROL_HANDSHAKE is set, so don't manipulate RTS\n");
1145  CloseHandle(hcom);
1146  return;
1147  }
1148  ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
1149  /* XP returns some values in the low nibble, so mask them out*/
1150  defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
1151  if(defaultStat & MS_CTS_ON)
1152  {
1153  ok(EscapeCommFunction(hcom, CLRRTS), "EscapeCommFunction failed to clear RTS\n");
1154  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1155  ok ((ModemStat & MS_CTS_ON) == 0, "CTS didn't react: 0x%04x, expected 0x%04x\n",
1156  ModemStat, (defaultStat & ~MS_CTS_ON));
1157  ok(EscapeCommFunction(hcom, SETRTS), "EscapeCommFunction failed to clear RTS\n");
1158  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1159  ok (ModemStat == defaultStat, "Failed to restore CTS: 0x%04x, expected 0x%04x\n",
1160  ModemStat, defaultStat);
1161  }
1162  else
1163  {
1164  ok(EscapeCommFunction(hcom, SETRTS), "EscapeCommFunction failed to set RTS\n");
1165  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1166  ok ((ModemStat & MS_CTS_ON) == MS_CTS_ON,
1167  "CTS didn't react: 0x%04x, expected 0x%04x\n",
1168  ModemStat, (defaultStat | MS_CTS_ON));
1169  ok(EscapeCommFunction(hcom, CLRRTS), "EscapeCommFunction failed to clear RTS\n");
1170  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1171  ok (ModemStat == defaultStat, "Failed to restore CTS: 0x%04x, expected 0x%04x\n",
1172  ModemStat, defaultStat);
1173  }
1174 
1175  CloseHandle(hcom);
1176 }
1177 
1178 static void test_LoopbackDtrDcd(void)
1179 {
1180  HANDLE hcom;
1181  DWORD ModemStat = 0, defaultStat = 0;
1182  DCB dcb;
1183 
1184  if (!loopback_dtr_dcd) return;
1185 
1186  hcom = test_OpenComm(FALSE);
1187  if (hcom == INVALID_HANDLE_VALUE) return;
1188 
1189  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1190  if (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
1191  {
1192  trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
1193  CloseHandle(hcom);
1194  return;
1195  }
1196  ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
1197  /* XP returns some values in the low nibble, so mask them out*/
1198  defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
1199  if(defaultStat & MS_RLSD_ON)
1200  {
1201  ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
1202  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1203  ok ((ModemStat & MS_RLSD_ON) == 0, "RLSD didn't react: 0x%04x, expected 0x%04x\n",
1204  ModemStat, (defaultStat & ~MS_RLSD_ON));
1205  ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
1206  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1207  ok (ModemStat == defaultStat, "Failed to restore RLSD: 0x%04x, expected 0x%04x\n",
1208  ModemStat, defaultStat);
1209  }
1210  else
1211  {
1212  ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
1213  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1214  ok ((ModemStat & MS_RLSD_ON) == MS_RLSD_ON,
1215  "RLSD didn't react: 0x%04x, expected 0x%04x\n",
1216  ModemStat, (defaultStat | MS_RLSD_ON));
1217  ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
1218  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1219  ok (ModemStat == defaultStat, "Failed to restore RLSD: 0x%04x, expected 0x%04x\n",
1220  ModemStat, defaultStat);
1221  }
1222 
1223  CloseHandle(hcom);
1224 }
1225 
1226 static void test_LoopbackDtrDsr(void)
1227 {
1228  HANDLE hcom;
1229  DWORD ModemStat = 0, defaultStat = 0;
1230  DCB dcb;
1231 
1232  if (!loopback_dtr_dsr) return;
1233 
1234  hcom = test_OpenComm(FALSE);
1235  if (hcom == INVALID_HANDLE_VALUE) return;
1236 
1237  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1238  if (dcb.fDtrControl == DTR_CONTROL_DISABLE)
1239  {
1240  trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
1241  CloseHandle(hcom);
1242  return;
1243  }
1244  ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
1245  /* XP returns some values in the low nibble, so mask them out*/
1246  defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
1247  if(defaultStat & MS_DSR_ON)
1248  {
1249  ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
1250  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1251  ok ((ModemStat & MS_DSR_ON) == 0, "CTS didn't react: 0x%04x, expected 0x%04x\n",
1252  ModemStat, (defaultStat & ~MS_DSR_ON));
1253  ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to clear DTR\n");
1254  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1255  ok (ModemStat == defaultStat, "Failed to restore DSR: 0x%04x, expected 0x%04x\n",
1256  ModemStat, defaultStat);
1257  }
1258  else
1259  {
1260  ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
1261  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1262  ok ((ModemStat & MS_DSR_ON) == MS_DSR_ON,
1263  "CTS didn't react: 0x%04x,expected 0x%04x\n",
1264  ModemStat, (defaultStat | MS_DSR_ON));
1265  ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
1266  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1267  ok (ModemStat == defaultStat, "Failed to restore DSR: 0x%04x, expected 0x%04x\n",
1268  ModemStat, defaultStat);
1269  }
1270 
1271  CloseHandle(hcom);
1272 }
1273 
1274 static void test_LoopbackDtrRing(void)
1275 {
1276  HANDLE hcom;
1277  DWORD ModemStat = 0, defaultStat = 0;
1278  DCB dcb;
1279 
1280  if (!loopback_dtr_ring) return;
1281 
1282  hcom = test_OpenComm(FALSE);
1283  if (hcom == INVALID_HANDLE_VALUE) return;
1284 
1285  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1286  if (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
1287  {
1288  trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
1289  CloseHandle(hcom);
1290  return;
1291  }
1292  ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
1293  /* XP returns some values in the low nibble, so mask them out*/
1294  defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
1295  if(defaultStat & MS_RING_ON)
1296  {
1297  ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
1298  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1299  ok ((ModemStat & MS_RING_ON) == 0, "RING didn't react: 0x%04x, expected 0x%04x\n",
1300  ModemStat, (defaultStat & ~MS_RING_ON));
1301  ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
1302  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1303  ok (ModemStat == defaultStat, "Failed to restore RING: 0x%04x, expected 0x%04x\n",
1304  ModemStat, defaultStat);
1305  }
1306  else
1307  {
1308  ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
1309  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1310  ok ((ModemStat & MS_RING_ON) == MS_RING_ON,
1311  "RING didn't react: 0x%04x,expected 0x%04x\n",
1312  ModemStat, (defaultStat | MS_RING_ON));
1313  ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
1314  ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
1315  ok (ModemStat == defaultStat, "Failed to restore RING: 0x%04x, expected 0x%04x\n",
1316  ModemStat, defaultStat);
1317  }
1318 
1319  CloseHandle(hcom);
1320 }
1321 
1322 /*
1323  * Set up a WaitCommEvent for anything in the receive buffer,
1324  * then write to TX to put a character
1325  * into the RX buffer
1326  * Need Loopback TX->RX
1327 */
1328 
1329 static void test_WaitRx(void)
1330 {
1331  OVERLAPPED overlapped, overlapped_w;
1332  HANDLE hcom, hComPortEvent, hComWriteEvent;
1333  DWORD before, after, after1, diff, success_wait = FALSE, success_write;
1334  DWORD err_wait, err_write, written, evtmask=0;
1335 
1336  if (!loopback_txd_rxd) return;
1337 
1338  hcom = test_OpenComm(TRUE);
1339  if (hcom == INVALID_HANDLE_VALUE) return;
1340 
1341  ok(SetCommMask(hcom, EV_RXCHAR), "SetCommMask failed\n");
1342  hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
1343  ok(hComPortEvent != 0, "CreateEvent failed\n");
1344  ZeroMemory( &overlapped, sizeof(overlapped));
1345  overlapped.hEvent = hComPortEvent;
1346 
1347  hComWriteEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
1348  ok(hComWriteEvent != NULL, "CreateEvent res %d\n", GetLastError());
1349  ZeroMemory( &overlapped_w, sizeof(overlapped_w));
1350  overlapped_w.hEvent = hComWriteEvent;
1351 
1352  before = GetTickCount();
1353  success_wait = WaitCommEvent(hcom, &evtmask, &overlapped);
1354  err_wait = GetLastError();
1355  after = GetTickCount();
1356  trace("Success 0x%08x err %d evtmask 0x%08x\n", success_wait, err_wait, evtmask);
1357  ok(success_wait || err_wait == ERROR_IO_PENDING, "overlapped WaitCommEvent failed\n");
1358  trace("overlapped WaitCommEvent returned.\n");
1359 
1360  success_write= WriteFile(hcom, "X", 1, &written, &overlapped_w);
1361  err_write = GetLastError();
1362  ok(success_write || err_write == ERROR_IO_PENDING,
1363  "overlapped WriteFile failed, err %d\n",
1364  err_write);
1365 
1366  if (!success_write && (err_write == ERROR_IO_PENDING)) {
1367  success_write = WaitForSingleObjectEx(hComWriteEvent, TIMEOUT, TRUE);
1368  err_write = GetLastError();
1369  ok(success_write == WAIT_OBJECT_0, "WaitForSingleObjectEx, res %d, err %d\n",
1370  success_write, err_write);
1371  }
1372  Sleep(TIMEOUT >>1);
1373  success_write = GetOverlappedResult(hcom, &overlapped_w, &written, FALSE);
1374  err_write = GetLastError();
1375 
1376  trace("Write after Wait res 0x%08x err %d\n",success_write, err_write);
1377  ok(success_write && written ==1, "Write after Wait res 0x%08x err %d\n",
1378  success_write, err_write);
1379 
1380  if (!success_wait && (err_wait == ERROR_IO_PENDING)) {
1381  success_wait = WaitForSingleObjectEx(hComPortEvent, TIMEOUT, TRUE);
1382  err_wait = GetLastError();
1383  ok(success_wait == WAIT_OBJECT_0, "wait hComPortEvent, res 0x%08x, err %d\n",
1384  success_wait, err_wait);
1385  }
1386  success_wait = GetOverlappedResult(hcom, &overlapped, &written, FALSE);
1387  err_wait = GetLastError();
1388  after1 = GetTickCount();
1389  trace("Success 0x%08x err %d evtmask 0x%08x diff1 %d, diff2 %d\n",
1390  success_wait, err_wait, evtmask, after-before, after1-before);
1391 
1392  ok(evtmask & EV_RXCHAR, "Detect EV_RXCHAR: 0x%08x, expected 0x%08x\n",
1393  evtmask, EV_RXCHAR);
1394  diff = after1 - before;
1395  ok ((diff > (TIMEOUT>>1) -TIMEDELTA) && (diff < (TIMEOUT>>1) + TIMEDELTA),
1396  "Unexpected time %d, expected around %d\n", diff, TIMEOUT>>1);
1397 
1398  CloseHandle(hcom);
1399 }
1400 
1401 /* Change the controlling line after the given timeout to the given state
1402  By the loopback, this should trigger the WaitCommEvent
1403 */
1405 {
1406  DWORD_PTR *args = arg;
1407  DWORD timeout = args[0];
1408  DWORD ctl = args[1];
1409  HANDLE hcom = (HANDLE) args[2];
1410  HANDLE hComPortEvent = (HANDLE) args[3];
1411  DWORD success, err;
1412 
1413  trace("toggle_ctlLine timeout %d ctl 0x%08x handle %p\n", timeout, ctl, hcom );
1414  Sleep(timeout);
1415  ok(EscapeCommFunction(hcom, ctl),"EscapeCommFunction 0x%08x failed\n", ctl);
1416  trace("toggle_ctline done\n");
1417  success = WaitForSingleObjectEx(hComPortEvent, TIMEOUT, TRUE);
1418  err = GetLastError();
1419  trace("toggle_ctline WaitForSingleObjectEx res 0x%08x err %d\n",
1420  success, err);
1421  return 0;
1422 }
1423 
1424 /*
1425  * Wait for a change in CTS
1426  * Needs Loopback from DTR to CTS
1427  */
1428 static void test_WaitCts(void)
1429 {
1430  DCB dcb;
1432  HANDLE hcom, hComPortEvent, alarmThread;
1433  DWORD_PTR args[4];
1434  DWORD alarmThreadId, before, after, after1, diff, success, err, written, evtmask=0, defaultStat = 0;
1435 
1436  if (!loopback_rts_cts) return;
1437 
1438  hcom = test_OpenComm(TRUE);
1439  if (hcom == INVALID_HANDLE_VALUE) return;
1440 
1441  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1442  dcb.fRtsControl=RTS_CONTROL_ENABLE;
1443  dcb.fDtrControl=DTR_CONTROL_ENABLE;
1444  ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
1445  if (dcb.fDtrControl == RTS_CONTROL_DISABLE)
1446  {
1447  trace("RTS_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
1448  CloseHandle(hcom);
1449  return;
1450  }
1451  args[0]= TIMEOUT >>1;
1452  ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
1453  if(defaultStat & MS_CTS_ON)
1454  args[1] = CLRRTS;
1455  else
1456  args[1] = SETRTS;
1457  args[2]=(DWORD_PTR)hcom;
1458 
1459  trace("test_WaitCts timeout %ld clt 0x%08lx handle %p\n",args[0], args[1], hcom);
1460 
1461  ok(SetCommMask(hcom, EV_CTS), "SetCommMask failed\n");
1462  hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
1463  ok(hComPortEvent != 0, "CreateEvent failed\n");
1464  args[3] = (DWORD_PTR)hComPortEvent;
1465  alarmThread = CreateThread(NULL, 0, toggle_ctlLine, args, 0, &alarmThreadId);
1466  /* Wait a minimum to let the thread start up */
1467  Sleep(10);
1468  trace("Thread created\n");
1469  ok(alarmThread !=0 , "CreateThread Failed\n");
1470 
1471  ZeroMemory( &overlapped, sizeof(overlapped));
1472  overlapped.hEvent = hComPortEvent;
1473  before = GetTickCount();
1474  success = WaitCommEvent(hcom, &evtmask, &overlapped);
1475  err = GetLastError();
1476  after = GetTickCount();
1477 
1478  trace("Success 0x%08x err %d evtmask 0x%08x\n", success, err, evtmask);
1479  ok(success || err == ERROR_IO_PENDING, "overlapped WaitCommEvent failed\n");
1480  trace("overlapped WaitCommEvent returned.\n");
1481  if (!success && (err == ERROR_IO_PENDING))
1482  ok(WaitForSingleObjectEx(hComPortEvent, TIMEOUT, TRUE) == 0,
1483  "WaitCts hComPortEvent failed\n");
1484  success = GetOverlappedResult(hcom, &overlapped, &written, FALSE);
1485  err = GetLastError();
1486  after1 = GetTickCount();
1487  trace("Success 0x%08x err %d evtmask 0x%08x diff1 %d, diff2 %d\n",
1488  success, err, evtmask, after-before, after1-before);
1489 
1490  ok(evtmask & EV_CTS, "Failed to detect EV_CTS: 0x%08x, expected 0x%08x\n",
1491  evtmask, EV_CTS);
1492  ok(GetCommModemStatus(hcom, &evtmask), "GetCommModemStatus failed\n");
1493  if(defaultStat & MS_CTS_ON)
1494  ok((evtmask & MS_CTS_ON) == 0,"CTS didn't change state!\n");
1495  else
1496  ok((evtmask & MS_CTS_ON), "CTS didn't change state!\n");
1497 
1498  diff = after1 - before;
1499  ok ((diff > (TIMEOUT>>1) -TIMEDELTA) && (diff < (TIMEOUT>>1) + TIMEDELTA),
1500  "Unexpected time %d, expected around %d\n", diff, TIMEOUT>>1);
1501 
1502  /*restore RTS Settings*/
1503  if(defaultStat & MS_CTS_ON)
1504  args[1] = SETRTS;
1505  else
1506  args[1] = CLRRTS;
1507 
1508  CloseHandle(hcom);
1509  ok( !WaitForSingleObject( alarmThread, 10000 ), "thread still running\n" );
1510  CloseHandle( alarmThread );
1511 }
1512 
1513 /* Change the Comm Mask while a Wait is going on
1514  WaitCommevent should return with a EVTMASK set to zero
1515 */
1517 {
1518  DWORD_PTR *args = arg;
1519  DWORD timeout = args[0];
1520  HANDLE hcom = (HANDLE) args[1];
1521 
1522  trace(" Changing CommMask on the fly for handle %p after timeout %d\n",
1523  hcom, timeout);
1524  Sleep(timeout);
1525  ok(SetCommMask(hcom, 0),"SetCommMask %p failed\n", hcom);
1526  trace("SetCommMask changed\n");
1527  return 0;
1528 }
1529 
1530 /* Set up a Wait for a change on CTS. We don't toggle any line, but we
1531  reset the CommMask and expect the wait to return with a mask of 0
1532  No special port connections needed
1533 */
1534 static void test_AbortWaitCts(void)
1535 {
1536  DCB dcb;
1538  HANDLE hcom, hComPortEvent, alarmThread;
1539  DWORD_PTR args[2];
1540  DWORD alarmThreadId, before, after, after1, diff, success, err, written, evtmask=0;
1541 
1542  hcom = test_OpenComm(TRUE);
1543  if (hcom == INVALID_HANDLE_VALUE) return;
1544 
1545  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1546  if (dcb.fDtrControl == RTS_CONTROL_DISABLE)
1547  {
1548  trace("RTS_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
1549  CloseHandle(hcom);
1550  return;
1551  }
1552  args[0]= TIMEOUT >>1;
1553  args[1]= (DWORD_PTR)hcom;
1554 
1555  trace("test_AbortWaitCts timeout %ld handle %p\n",args[0], hcom);
1556 
1557  ok(SetCommMask(hcom, EV_CTS), "SetCommMask failed\n");
1558  hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
1559  ok(hComPortEvent != 0, "CreateEvent failed\n");
1560  alarmThread = CreateThread(NULL, 0, reset_CommMask, args, 0, &alarmThreadId);
1561  /* Wait a minimum to let the thread start up */
1562  Sleep(10);
1563  trace("Thread created\n");
1564  ok(alarmThread !=0 , "CreateThread Failed\n");
1565 
1566  ZeroMemory( &overlapped, sizeof(overlapped));
1567  overlapped.hEvent = hComPortEvent;
1568  before = GetTickCount();
1569  success = WaitCommEvent(hcom, &evtmask, &overlapped);
1570  err = GetLastError();
1571  after = GetTickCount();
1572 
1573  trace("Success 0x%08x err %d evtmask 0x%08x\n", success, err, evtmask);
1574  ok(success || err == ERROR_IO_PENDING, "overlapped WaitCommEvent failed\n");
1575  trace("overlapped WaitCommEvent returned.\n");
1576  if (!success && (err == ERROR_IO_PENDING))
1577  ok(WaitForSingleObjectEx(hComPortEvent, TIMEOUT, TRUE) == 0,
1578  "AbortWaitCts hComPortEvent failed\n");
1579  success = GetOverlappedResult(hcom, &overlapped, &written, FALSE);
1580  err = GetLastError();
1581  after1 = GetTickCount();
1582  trace("Success 0x%08x err %d evtmask 0x%08x diff1 %d, diff2 %d\n",
1583  success, err, evtmask, after-before, after1-before);
1584 
1585  ok(evtmask == 0, "Incorrect EventMask 0x%08x returned on Wait aborted bu SetCommMask, expected 0x%08x\n",
1586  evtmask, 0);
1587  ok(GetCommModemStatus(hcom, &evtmask), "GetCommModemStatus failed\n");
1588  diff = after1 - before;
1589  ok ((diff > (TIMEOUT>>1) -TIMEDELTA) && (diff < (TIMEOUT>>1) + TIMEDELTA),
1590  "Unexpected time %d, expected around %d\n", diff, TIMEOUT>>1);
1591 
1592  CloseHandle(hcom);
1593  ok( !WaitForSingleObject( alarmThread, 10000 ), "thread still running\n" );
1594  CloseHandle( alarmThread );
1595 }
1596 
1597 /*
1598  * Wait for a change in DSR
1599  * Needs Loopback from DTR to DSR
1600  */
1601 static void test_WaitDsr(void)
1602 {
1603  DCB dcb;
1605  HANDLE hcom, hComPortEvent, alarmThread;
1606  DWORD_PTR args[3];
1607  DWORD alarmThreadId, before, after, after1, diff, success, err, written, evtmask=0, defaultStat = 0;
1608 
1609  if (!loopback_dtr_dsr) return;
1610 
1611  hcom = test_OpenComm(TRUE);
1612  if (hcom == INVALID_HANDLE_VALUE) return;
1613 
1614  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1615  if (dcb.fDtrControl == DTR_CONTROL_DISABLE)
1616  {
1617  trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
1618  CloseHandle(hcom);
1619  return;
1620  }
1621  args[0]= TIMEOUT >>1;
1622  ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
1623  if(defaultStat & MS_DSR_ON)
1624  args[1] = CLRDTR;
1625  else
1626  args[1] = SETDTR;
1627  args[2]= (DWORD_PTR)hcom;
1628 
1629  trace("test_WaitDsr timeout %ld clt 0x%08lx handle %p\n",args[0], args[1], hcom);
1630 
1631  ok(SetCommMask(hcom, EV_DSR), "SetCommMask failed\n");
1632  hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
1633  ok(hComPortEvent != 0, "CreateEvent failed\n");
1634  alarmThread = CreateThread(NULL, 0, toggle_ctlLine, args, 0, &alarmThreadId);
1635  ok(alarmThread !=0 , "CreateThread Failed\n");
1636 
1637  ZeroMemory( &overlapped, sizeof(overlapped));
1638  overlapped.hEvent = hComPortEvent;
1639  before = GetTickCount();
1640  success = WaitCommEvent(hcom, &evtmask, &overlapped);
1641  err = GetLastError();
1642  after = GetTickCount();
1643 
1644  trace("Success 0x%08x err %d evtmask 0x%08x\n", success, err, evtmask);
1645  ok(success || err == ERROR_IO_PENDING, "overlapped WaitCommEvent failed\n");
1646  trace("overlapped WaitCommEvent returned.\n");
1647  if (!success && (err == ERROR_IO_PENDING))
1648  ok(WaitForSingleObjectEx(hComPortEvent, TIMEOUT, TRUE) == 0,
1649  "wait hComPortEvent failed\n");
1650  success = GetOverlappedResult(hcom, &overlapped, &written, FALSE);
1651  err = GetLastError();
1652  after1 = GetTickCount();
1653  trace("Success 0x%08x err %d evtmask 0x%08x diff1 %d, diff2 %d\n",
1654  success, err, evtmask, after-before, after1-before);
1655 
1656  ok(evtmask & EV_DSR, "Failed to detect EV_DSR: 0x%08x, expected 0x%08x\n",
1657  evtmask, EV_DSR);
1658  ok(GetCommModemStatus(hcom, &evtmask), "GetCommModemStatus failed\n");
1659  if(defaultStat & MS_DSR_ON)
1660  ok((evtmask & MS_DSR_ON) == 0,"DTR didn't change state!\n");
1661  else
1662  ok((evtmask & MS_DSR_ON), "DTR didn't change state!\n");
1663 
1664  diff = after1 - before;
1665  ok ((diff > (TIMEOUT>>1) -TIMEDELTA) && (diff < (TIMEOUT>>1) + TIMEDELTA),
1666  "Unexpected time %d, expected around %d\n", diff, TIMEOUT>>1);
1667 
1668  /*restore RTS Settings*/
1669  if(defaultStat & MS_DSR_ON)
1670  args[1] = SETDTR;
1671  else
1672  args[1] = CLRDTR;
1673 
1674  CloseHandle(hcom);
1675  ok( !WaitForSingleObject( alarmThread, 10000 ), "thread still running\n" );
1676  CloseHandle( alarmThread );
1677 }
1678 
1679 /*
1680  * Wait for a Ring
1681  * Needs Loopback from DTR to RING
1682  */
1683 static void test_WaitRing(void)
1684 {
1685  DCB dcb;
1687  HANDLE hcom, hComPortEvent, alarmThread;
1688  DWORD_PTR args[3];
1689  DWORD alarmThreadId, before, after, after1, diff, success, err, written, evtmask=0, defaultStat;
1690  BOOL ret;
1691 
1692  if (!loopback_dtr_ring) return;
1693 
1694  hcom = test_OpenComm(TRUE);
1695  if (hcom == INVALID_HANDLE_VALUE) return;
1696 
1697  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1698  if (dcb.fDtrControl == DTR_CONTROL_DISABLE)
1699  {
1700  trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
1701  CloseHandle(hcom);
1702  return;
1703  }
1704  args[0]= TIMEOUT >>1;
1705  ok((ret = GetCommModemStatus(hcom, &defaultStat)), "GetCommModemStatus failed\n");
1706  if (!ret) {
1707  skip("modem status failed -> skip.\n");
1708  CloseHandle(hcom);
1709  return;
1710  }
1711  if(defaultStat & MS_RING_ON)
1712  args[1] = CLRDTR;
1713  else
1714  args[1] = SETDTR;
1715  args[2]=(DWORD_PTR) hcom;
1716 
1717  trace("test_WaitRing timeout %ld clt 0x%08lx handle %p\n",args[0], args[1], hcom);
1718 
1719  ok(SetCommMask(hcom, EV_RING), "SetCommMask failed\n");
1720  hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
1721  ok(hComPortEvent != 0, "CreateEvent failed\n");
1722  alarmThread = CreateThread(NULL, 0, toggle_ctlLine, args, 0, &alarmThreadId);
1723  ok(alarmThread !=0 , "CreateThread Failed\n");
1724 
1725  ZeroMemory( &overlapped, sizeof(overlapped));
1726  overlapped.hEvent = hComPortEvent;
1727  before = GetTickCount();
1728  success = WaitCommEvent(hcom, &evtmask, &overlapped);
1729  err = GetLastError();
1730  after = GetTickCount();
1731 
1732  trace("Success 0x%08x err %d evtmask 0x%08x\n", success, err, evtmask);
1733  ok(success || err == ERROR_IO_PENDING, "overlapped WaitCommEvent failed\n");
1734  trace("overlapped WaitCommEvent returned.\n");
1735  if (!success && (err == ERROR_IO_PENDING))
1736  ok(WaitForSingleObjectEx(hComPortEvent, TIMEOUT, TRUE) == 0,
1737  "wait hComPortEvent failed\n");
1738  success = GetOverlappedResult(hcom, &overlapped, &written, FALSE);
1739  err = GetLastError();
1740  after1 = GetTickCount();
1741  trace("Success 0x%08x err %d evtmask 0x%08x diff1 %d, diff2 %d\n",
1742  success, err, evtmask, after-before, after1-before);
1743 
1744  ok(evtmask & EV_RING, "Failed to detect EV_RING: 0x%08x, expected 0x%08x\n",
1745  evtmask, EV_RING);
1746  ok(GetCommModemStatus(hcom, &evtmask), "GetCommModemStatus failed\n");
1747  if(defaultStat & MS_RING_ON)
1748  ok((evtmask & MS_RING_ON) == 0,"DTR didn't change state!\n");
1749  else
1750  ok((evtmask & MS_RING_ON), "DTR didn't change state!\n");
1751 
1752  diff = after1 - before;
1753  ok ((diff > (TIMEOUT>>1) -TIMEDELTA) && (diff < (TIMEOUT>>1) + TIMEDELTA),
1754  "Unexpected time %d, expected around %d\n", diff, TIMEOUT>>1);
1755 
1756  /*restore RTS Settings*/
1757  if(defaultStat & MS_RING_ON)
1758  args[1] = SETDTR;
1759  else
1760  args[1] = CLRDTR;
1761 
1762  CloseHandle(hcom);
1763  ok( !WaitForSingleObject( alarmThread, 10000 ), "thread still running\n" );
1764  CloseHandle( alarmThread );
1765 }
1766 /*
1767  * Wait for a change in DCD
1768  * Needs Loopback from DTR to DCD
1769  */
1770 static void test_WaitDcd(void)
1771 {
1772  DCB dcb;
1774  HANDLE hcom, hComPortEvent, alarmThread;
1775  DWORD_PTR args[3];
1776  DWORD alarmThreadId, before, after, after1, diff, success, err, written, evtmask=0, defaultStat = 0;
1777 
1778  if (!loopback_dtr_dcd) return;
1779 
1780  hcom = test_OpenComm(TRUE);
1781  if (hcom == INVALID_HANDLE_VALUE) return;
1782 
1783  ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
1784  if (dcb.fDtrControl == DTR_CONTROL_DISABLE)
1785  {
1786  trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
1787  CloseHandle(hcom);
1788  return;
1789  }
1790  args[0]= TIMEOUT >>1;
1791  ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
1792  if(defaultStat & MS_RLSD_ON)
1793  args[1] = CLRDTR;
1794  else
1795  args[1] = SETDTR;
1796  args[2]= (DWORD_PTR)hcom;
1797 
1798  trace("test_WaitDcd timeout %ld clt 0x%08lx handle %p\n",args[0], args[1], hcom);
1799 
1800  ok(SetCommMask(hcom, EV_RLSD), "SetCommMask failed\n");
1801  hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
1802  ok(hComPortEvent != 0, "CreateEvent failed\n");
1803  alarmThread = CreateThread(NULL, 0, toggle_ctlLine, args, 0, &alarmThreadId);
1804  ok(alarmThread !=0 , "CreateThread Failed\n");
1805 
1806  ZeroMemory( &overlapped, sizeof(overlapped));
1807  overlapped.hEvent = hComPortEvent;
1808  before = GetTickCount();
1809  success = WaitCommEvent(hcom, &evtmask, &overlapped);
1810  err = GetLastError();
1811  after = GetTickCount();
1812 
1813  trace("Success 0x%08x err %d evtmask 0x%08x\n", success, err, evtmask);
1814  ok(success || err == ERROR_IO_PENDING, "overlapped WaitCommEvent failed\n");
1815  trace("overlapped WaitCommEvent returned.\n");
1816  if (!success && (err == ERROR_IO_PENDING))
1817  ok(WaitForSingleObjectEx(hComPortEvent, TIMEOUT, TRUE) == 0,
1818  "wait hComPortEvent failed\n");
1819  success = GetOverlappedResult(hcom, &overlapped, &written, FALSE);
1820  err = GetLastError();
1821  after1 = GetTickCount();
1822  trace("Success 0x%08x err %d evtmask 0x%08x diff1 %d, diff2 %d\n",
1823  success, err, evtmask, after-before, after1-before);
1824 
1825  ok(evtmask & EV_RLSD, "Failed to detect EV_RLSD: 0x%08x, expected 0x%08x\n",
1826  evtmask, EV_RLSD);
1827  ok(GetCommModemStatus(hcom, &evtmask), "GetCommModemStatus failed\n");
1828  if(defaultStat & MS_RLSD_ON)
1829  ok((evtmask & MS_RLSD_ON) == 0,"DTR didn't change state!\n");
1830  else
1831  ok((evtmask & MS_RLSD_ON), "DTR didn't change state!\n");
1832 
1833  diff = after1 - before;
1834  ok ((diff > (TIMEOUT>>1) -TIMEDELTA) && (diff < (TIMEOUT>>1) + TIMEDELTA),
1835  "Unexpected time %d, expected around %d\n", diff, TIMEOUT>>1);
1836 
1837  /*restore RTS Settings*/
1838  if(defaultStat & MS_RLSD_ON)
1839  args[1] = SETDTR;
1840  else
1841  args[1] = CLRDTR;
1842 
1843  CloseHandle(hcom);
1844  ok( !WaitForSingleObject( alarmThread, 10000 ), "thread still running\n" );
1845  CloseHandle( alarmThread );
1846 }
1847 
1848 /*
1849  Set Break after timeout
1850 */
1852 {
1853  DWORD_PTR *args = arg;
1854  DWORD timeout = args[0];
1855  HANDLE hcom = (HANDLE) args[1];
1856 
1857  trace("SetCommBreak for handle %p after timeout %d\n",
1858  hcom, timeout);
1859  Sleep(timeout);
1860  ok(SetCommBreak(hcom),"SetCommBreak %p failed\n", hcom);
1861  trace("SetCommBreak done\n");
1862  return 0;
1863 }
1864 
1865 /*
1866  Wait for the Break condition (TX resp. RX active)
1867  Needs Loopback TX-RX
1868 */
1869 static void test_WaitBreak(void)
1870 {
1872  HANDLE hcom, hComPortEvent, alarmThread;
1873  DWORD_PTR args[2];
1874  DWORD alarmThreadId, before, after, after1, diff, success, err, written, evtmask=0;
1875 
1876  if (!loopback_txd_rxd) return;
1877 
1878  hcom = test_OpenComm(TRUE);
1879  if (hcom == INVALID_HANDLE_VALUE) return;
1880 
1881  ok(SetCommMask(hcom, EV_BREAK), "SetCommMask failed\n");
1882  hComPortEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
1883  ok(hComPortEvent != 0, "CreateEvent failed\n");
1884 
1885  trace("test_WaitBreak\n");
1886  args[0]= TIMEOUT >>1;
1887  args[1]= (DWORD_PTR)hcom;
1888  alarmThread = CreateThread(NULL, 0, set_CommBreak, args, 0, &alarmThreadId);
1889  /* Wait a minimum to let the thread start up */
1890  Sleep(10);
1891  trace("Thread created\n");
1892  ok(alarmThread !=0 , "CreateThread Failed\n");
1893 
1894  ZeroMemory( &overlapped, sizeof(overlapped));
1895  overlapped.hEvent = hComPortEvent;
1896  before = GetTickCount();
1897  success = WaitCommEvent(hcom, &evtmask, &overlapped);
1898  err = GetLastError();
1899  after = GetTickCount();
1900 
1901  trace("Success 0x%08x err %d evtmask 0x%08x\n", success, err, evtmask);
1902  ok(success || err == ERROR_IO_PENDING, "overlapped WaitCommEvent failed\n");
1903  trace("overlapped WaitCommEvent returned.\n");
1904 
1905  if (!success && (err == ERROR_IO_PENDING))
1906  {
1907  success = WaitForSingleObjectEx(hComPortEvent, TIMEOUT, TRUE);
1908  ok(!success, "wait hComPortEvent res %d\n", GetLastError());
1909  }
1910  success = GetOverlappedResult(hcom, &overlapped, &written, FALSE);
1911  err = GetLastError();
1912  after1 = GetTickCount();
1913  trace("Success 0x%08x err %d evtmask 0x%08x diff1 %d, diff2 %d\n",
1914  success, err, evtmask, after-before, after1-before);
1915 
1916  ok(evtmask & EV_BREAK, "Failed to detect EV_BREAK: 0x%08x, expected 0x%08x\n",
1917  evtmask, EV_BREAK);
1918  ok(GetCommModemStatus(hcom, &evtmask), "GetCommModemStatus failed\n");
1919 
1920  diff = after1 - before;
1921  ok ((diff > (TIMEOUT>>1) -TIMEDELTA) && (diff < (TIMEOUT>>1) + TIMEDELTA),
1922  "Unexpected time %d, expected around %d\n", diff, TIMEOUT>>1);
1923 
1924  ok(ClearCommBreak(hcom), "ClearCommBreak failed\n");
1925 
1926  CloseHandle(hcom);
1927  ok( !WaitForSingleObject( alarmThread, 10000 ), "thread still running\n" );
1928  CloseHandle( alarmThread );
1929 }
1930 
1931 static void test_stdio(void)
1932 {
1933  DCB dcb;
1934 
1935  /* cygwin tries this to determine the stdin handle type */
1936  ok( !GetCommState( GetStdHandle(STD_INPUT_HANDLE), &dcb ), "GetCommState succeeded on stdin\n" );
1938  "got error %u\n", GetLastError() );
1939 }
1940 
1941 static void test_WaitCommEvent(void)
1942 {
1943  HANDLE hcom;
1944  DWORD evtmask, ret, bytes, before, after, last_event_time;
1945  OVERLAPPED ovl_wait;
1946 
1947  hcom = test_OpenComm(TRUE);
1948  if (hcom == INVALID_HANDLE_VALUE) return;
1949 
1950  test_GetModemStatus(hcom);
1951 
1952  ret = SetCommMask(hcom, 0x1fff);
1953  ok(ret, "SetCommMask error %d\n", GetLastError());
1954 
1955  S(U(ovl_wait)).Offset = 0;
1956  S(U(ovl_wait)).OffsetHigh = 0;
1957  ovl_wait.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
1958 
1959  trace("waiting 10 secs for com port events (turn on/off the device)...\n");
1960  last_event_time = 0;
1961  before = GetTickCount();
1962  do
1963  {
1964  evtmask = 0;
1965  SetLastError(0xdeadbeef);
1966  ret = WaitCommEvent(hcom, &evtmask, &ovl_wait);
1967  ok(!ret && GetLastError() == ERROR_IO_PENDING, "WaitCommEvent returned %d, error %d\n", ret, GetLastError());
1968  if (GetLastError() != ERROR_IO_PENDING) goto done; /* no point in further testing */
1969  for (;;)
1970  {
1971  ret = WaitForSingleObject(ovl_wait.hEvent, 500);
1972  after = GetTickCount();
1973  if (ret == WAIT_OBJECT_0)
1974  {
1975  last_event_time = after;
1976  ret = GetOverlappedResult(hcom, &ovl_wait, &bytes, FALSE);
1977  ok(ret, "GetOverlappedResult reported error %d\n", GetLastError());
1978  ok(bytes == sizeof(evtmask), "expected %u, written %u\n", (UINT)sizeof(evtmask), bytes);
1979  trace("WaitCommEvent: got events %#x\n", evtmask);
1980  test_GetModemStatus(hcom);
1981  break;
1982  }
1983  else
1984  {
1985  if (last_event_time || after - before >= 10000) goto done;
1986  }
1987  }
1988  } while (after - before < 10000);
1989 
1990 done:
1991  CloseHandle(ovl_wait.hEvent);
1992  CloseHandle(hcom);
1993 }
1994 
1995 static void test_FlushFileBuffers(void)
1996 {
1997  HANDLE hcom;
1998  DWORD ret, bytes, errors;
1999  COMSTAT stat;
2000 
2001  hcom = test_OpenComm(FALSE);
2002  if (hcom == INVALID_HANDLE_VALUE) return;
2003 
2004  ret = WriteFile(hcom, "\0\0\0\0\0\0\0", 7, &bytes, NULL);
2005  ok(ret, "WriteFile error %d\n", GetLastError());
2006  ok(bytes == 7, "expected 7, got %u\n", bytes);
2007 
2008  ret = FlushFileBuffers(hcom);
2009  ok(ret, "FlushFileBuffers error %d\n", GetLastError());
2010 
2011  ret = ClearCommError(hcom, &errors, &stat);
2012  ok(ret, "ClearCommError error %d\n", GetLastError());
2013  ok(stat.cbInQue == 0, "expected 0, got %d bytes in InQueue\n", stat.cbInQue);
2014  ok(stat.cbOutQue == 0, "expected 0, got %d bytes in OutQueue\n", stat.cbOutQue);
2015  ok(errors == 0, "expected errors 0, got %#x\n", errors);
2016 
2017  CloseHandle(hcom);
2018 }
2019 
2020 static void test_read_write(void)
2021 {
2022  static const char atz[]="ATZ\r\n";
2023  char buf[256];
2024  HANDLE hcom;
2025  DCB dcb;
2027  DWORD ret, bytes, status, evtmask, before, after, last_event_time;
2028  OVERLAPPED ovl_wait;
2029  IO_STATUS_BLOCK iob;
2031  LONG i;
2032 
2033  if (!pNtReadFile || !pNtWriteFile)
2034  {
2035  win_skip("not running on NT, skipping test\n");
2036  return;
2037  }
2038 
2039  hcom = test_OpenComm(TRUE);
2040  if (hcom == INVALID_HANDLE_VALUE) return;
2041 
2042  ret = GetCommState(hcom, &dcb);
2043  ok(ret, "GetCommState error %d\n", GetLastError());
2044  dcb.BaudRate = 9600;
2045  dcb.ByteSize = 8;
2046  dcb.Parity = NOPARITY;
2047  dcb.fRtsControl = RTS_CONTROL_ENABLE;
2048  dcb.fDtrControl = DTR_CONTROL_ENABLE;
2049  dcb.StopBits = ONESTOPBIT;
2050  ret = SetCommState(hcom, &dcb);
2051  ok(ret, "SetCommState error %d\n", GetLastError());
2052 
2053  memset(&timeouts, 0, sizeof(timeouts));
2054  timeouts.ReadTotalTimeoutConstant = TIMEOUT;
2055  ret = SetCommTimeouts(hcom, &timeouts);
2056  ok(ret,"SetCommTimeouts error %d\n", GetLastError());
2057 
2058  ret = SetupComm(hcom, 1024, 1024);
2059  ok(ret, "SetUpComm error %d\n", GetLastError());
2060 
2061  bytes = 0xdeadbeef;
2062  SetLastError(0xdeadbeef);
2063  ret = WriteFile(hcom, atz, 0, &bytes, NULL);
2064  ok(!ret, "WriteFile should fail\n");
2065  ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2066  ok(bytes == 0, "bytes %u\n", bytes);
2067 
2068  U(iob).Status = -1;
2069  iob.Information = -1;
2070  status = pNtWriteFile(hcom, 0, NULL, NULL, &iob, atz, 0, NULL, NULL);
2071  ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %#x\n", status);
2072  ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status);
2073  ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information);
2074 
2075  for (i = -20; i < 20; i++)
2076  {
2077  U(iob).Status = -1;
2078  iob.Information = -1;
2079  offset.QuadPart = (LONGLONG)i;
2080  status = pNtWriteFile(hcom, 0, NULL, NULL, &iob, atz, 0, &offset, NULL);
2081  if (i >= 0 || i == -1)
2082  {
2083  ok(status == STATUS_SUCCESS, "%d: expected STATUS_SUCCESS, got %#x\n", i, status);
2084  ok(U(iob).Status == STATUS_SUCCESS, "%d: expected STATUS_SUCCESS, got %#x\n", i, U(iob).Status);
2085  ok(iob.Information == 0, "%d: expected 0, got %lu\n", i, iob.Information);
2086  }
2087  else
2088  {
2089  ok(status == STATUS_INVALID_PARAMETER, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i, status);
2090  ok(U(iob).Status == -1, "%d: expected -1, got %#x\n", i, U(iob).Status);
2091  ok(iob.Information == -1, "%d: expected -1, got %ld\n", i, iob.Information);
2092  }
2093  }
2094 
2095  U(iob).Status = -1;
2096  iob.Information = -1;
2097  offset.QuadPart = 0;
2098  status = pNtWriteFile(hcom, 0, NULL, NULL, &iob, atz, sizeof(atz), &offset, NULL);
2099  ok(status == STATUS_PENDING || status == STATUS_SUCCESS, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status);
2100  /* Under Windows checking IO_STATUS_BLOCK right after the call leads
2101  * to races, iob.Status is either -1 or STATUS_SUCCESS, which means
2102  * that it's set only when the operation completes.
2103  */
2104  ret = WaitForSingleObject(hcom, TIMEOUT);
2105  if (ret == WAIT_TIMEOUT)
2106  {
2107  skip("Probably modem is not connected.\n");
2108  CloseHandle(hcom);
2109  return;
2110  }
2111  ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %d\n", ret);
2112  ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status);
2113  ok(iob.Information == sizeof(atz), "expected sizeof(atz), got %lu\n", iob.Information);
2114 
2115  ret = SetCommMask(hcom, EV_RXCHAR);
2116  ok(ret, "SetCommMask error %d\n", GetLastError());
2117 
2118  S(U(ovl_wait)).Offset = 0;
2119  S(U(ovl_wait)).OffsetHigh = 0;
2120  ovl_wait.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
2121 
2122  trace("waiting 3 secs for modem response...\n");
2123  last_event_time = 0;
2124  before = GetTickCount();
2125  do
2126  {
2127  evtmask = 0;
2128  SetLastError(0xdeadbeef);
2129  ret = WaitCommEvent(hcom, &evtmask, &ovl_wait);
2130  ok(!ret && GetLastError() == ERROR_IO_PENDING, "WaitCommEvent returned %d, error %d\n", ret, GetLastError());
2131  if (GetLastError() != ERROR_IO_PENDING) goto done; /* no point in further testing */
2132  for (;;)
2133  {
2134  ret = WaitForSingleObject(ovl_wait.hEvent, 100);
2135  after = GetTickCount();
2136  if (ret == WAIT_OBJECT_0)
2137  {
2138  trace("got modem response.\n");
2139 
2140  last_event_time = after;
2141  ret = GetOverlappedResult(hcom, &ovl_wait, &bytes, FALSE);
2142  ok(ret, "GetOverlappedResult reported error %d\n", GetLastError());
2143  ok(bytes == sizeof(evtmask), "expected sizeof(evtmask), got %u\n", bytes);
2144  ok(evtmask & EV_RXCHAR, "EV_RXCHAR should be set\n");
2145 
2146  bytes = 0xdeadbeef;
2147  SetLastError(0xdeadbeef);
2148  ret = ReadFile(hcom, buf, 0, &bytes, NULL);
2149  ok(!ret, "ReadFile should fail\n");
2150  ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2151  ok(bytes == 0, "bytes %u\n", bytes);
2152 
2153  U(iob).Status = -1;
2154  iob.Information = -1;
2155  status = pNtReadFile(hcom, 0, NULL, NULL, &iob, buf, 0, NULL, NULL);
2156  ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %#x\n", status);
2157  ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status);
2158  ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information);
2159 
2160  for (i = -20; i < 20; i++)
2161  {
2162  U(iob).Status = -1;
2163  iob.Information = -1;
2164  offset.QuadPart = (LONGLONG)i;
2165  status = pNtReadFile(hcom, 0, NULL, NULL, &iob, buf, 0, &offset, NULL);
2166  if (i >= 0)
2167  {
2168  ok(status == STATUS_SUCCESS, "%d: expected STATUS_SUCCESS, got %#x\n", i, status);
2169  ok(U(iob).Status == STATUS_SUCCESS, "%d: expected STATUS_SUCCESS, got %#x\n", i, U(iob).Status);
2170  ok(iob.Information == 0, "%d: expected 0, got %lu\n", i, iob.Information);
2171  }
2172  else
2173  {
2174  ok(status == STATUS_INVALID_PARAMETER, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i, status);
2175  ok(U(iob).Status == -1, "%d: expected -1, got %#x\n", i, U(iob).Status);
2176  ok(iob.Information == -1, "%d: expected -1, got %ld\n", i, iob.Information);
2177  }
2178  }
2179 
2180  U(iob).Status = -1;
2181  iob.Information = -1;
2182  offset.QuadPart = 0;
2183  status = pNtReadFile(hcom, 0, NULL, NULL, &iob, buf, 1, &offset, NULL);
2184  ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", status);
2185  ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status);
2186  ok(iob.Information == 1, "expected 1, got %lu\n", iob.Information);
2187  goto done;
2188  }
2189  else
2190  {
2191  if (last_event_time || after - before >= 3000) goto done;
2192  }
2193  }
2194  } while (after - before < 3000);
2195 
2196 done:
2197  CloseHandle(ovl_wait.hEvent);
2198  CloseHandle(hcom);
2199 }
2200 
2202 {
2203  HMODULE ntdll = GetModuleHandleA("ntdll.dll");
2204  if (ntdll)
2205  {
2206  pNtReadFile = (void *)GetProcAddress(ntdll, "NtReadFile");
2207  pNtWriteFile = (void *)GetProcAddress(ntdll, "NtWriteFile");
2208  }
2209 
2210  test_ClearCommError(); /* keep it the very first test */
2213  test_ReadTimeOut();
2214  test_waittxempty();
2221  test_WaitRx();
2222  test_WaitCts();
2224  test_WaitDsr();
2225  test_WaitRing();
2226  test_WaitDcd();
2227  test_WaitBreak();
2228  test_stdio();
2229  test_read_write();
2230 
2231  if (!winetest_interactive)
2232  {
2233  skip("interactive tests (set WINETEST_INTERACTIVE=1)\n");
2234  return;
2235  }
2236 
2238 }
BOOL WINAPI SetupComm(HANDLE handle, DWORD insize, DWORD outsize)
Definition: comm.c:718
#define MS_RLSD_ON
Definition: winbase.h:513
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define TIMEOUT
Definition: comm.c:30
struct _COMM_CONFIG COMMCONFIG
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
#define trace(...)
Definition: kmt_test.h:217
static void test_LoopbackCtsRts(void)
Definition: comm.c:1129
static void check_timeouts(const char *function, const TEST *ptest, int initial_value, const COMMTIMEOUTS *ptimeouts1, const COMMTIMEOUTS *ptimeouts2)
Definition: comm.c:534
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
VOID(* PIO_APC_ROUTINE)(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
Definition: nt_native.h:877
#define TEST_COUNT
Definition: comm.c:413
#define LOOPBACK_DTR_RING
Definition: comm.c:41
BOOL WINAPI SetCommMask(HANDLE handle, DWORD evtmask)
Definition: comm.c:768
static BOOL loopback_dtr_dsr
Definition: comm.c:50
#define DWORD_PTR
Definition: treelist.c:76
static void test_WaitCommEvent(void)
Definition: comm.c:1941
static HANDLE PIO_APC_ROUTINE void * apc_user
Definition: comm.c:54
BOOL WINAPI SetCommState(HANDLE handle, LPDCB lpdcb)
Definition: comm.c:807
#define RTS_CONTROL_ENABLE
Definition: winbase.h:518
BOOL WINAPI SetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts)
Definition: comm.c:1060
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void test_WaitBreak(void)
Definition: comm.c:1869
Definition: cdstruc.h:908
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOL old_style
Definition: comm.c:68
#define DTR_CONTROL_DISABLE
Definition: winbase.h:514
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define CP_ACP
Definition: compat.h:99
static void test_WaitCts(void)
Definition: comm.c:1428
#define RTS_CONTROL_HANDSHAKE
Definition: winbase.h:519
BOOL WINAPI ClearCommError(HANDLE handle, LPDWORD errors, LPCOMSTAT lpStat)
Definition: comm.c:663
#define U(x)
Definition: wordpad.c:44
static void test_BuildCommDCBAndTimeoutsA(const char *string, const TEST *ptest, int initial_value, const DCB *pexpected_dcb, const COMMTIMEOUTS *pexpected_timeouts)
Definition: comm.c:559
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
BOOL WINAPI BuildCommDCBAndTimeoutsW(LPCWSTR devid, LPDCB lpdcb, LPCOMMTIMEOUTS lptimeouts)
Definition: comm.c:476
GLintptr offset
Definition: glext.h:5920
#define check_timeouts_member(a)
Definition: comm.c:532
#define CALLBACK
Definition: compat.h:27
static HANDLE PIO_APC_ROUTINE void PIO_STATUS_BLOCK io_status
Definition: comm.c:54
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
#define TIMEDELTA
Definition: comm.c:33
START_TEST(comm)
Definition: comm.c:2201
DWORD cbOutQue
Definition: winbase.h:704
#define S(x)
Definition: test.h:190
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:152
__inline int before(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2414
void * arg
Definition: msvc.h:12
Definition: dhcpd.h:245
int winetest_interactive
static const TEST test[]
Definition: comm.c:73
#define RTS_CONTROL_DISABLE
Definition: winbase.h:517
#define ERROR_IO_PENDING
Definition: dderror.h:15
Definition: match.c:390
#define CLRRTS
Definition: winbase.h:222
DWORD cbInQue
Definition: winbase.h:703
#define ONESTOPBIT
Definition: winbase.h:439
#define EV_RXCHAR
Definition: winbase.h:417
static DWORD CALLBACK toggle_ctlLine(LPVOID arg)
Definition: comm.c:1404
static void test_LoopbackDtrDcd(void)
Definition: comm.c:1178
static HANDLE PIO_APC_ROUTINE void PIO_STATUS_BLOCK void ULONG length
Definition: comm.c:54
static BOOL loopback_rts_cts
Definition: comm.c:49
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:597
static DWORD CALLBACK set_CommBreak(LPVOID arg)
Definition: comm.c:1851
PWSTR StopBits[]
Definition: serial.c:37
static HANDLE hEvent
Definition: comm.c:54
static void test_FlushFileBuffers(void)
Definition: comm.c:1995
static void test_stdio(void)
Definition: comm.c:1931
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static HANDLE PIO_APC_ROUTINE void PIO_STATUS_BLOCK void ULONG PLARGE_INTEGER PULONG key
Definition: comm.c:54
static HANDLE PIO_APC_ROUTINE apc
Definition: comm.c:54
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
unsigned int BOOL
Definition: ntddk_ex.h:94
static void test_read_write(void)
Definition: comm.c:2020
long LONG
Definition: pedump.c:60
#define DTR_CONTROL_ENABLE
Definition: winbase.h:515
static void test_non_pending_errors(void)
Definition: comm.c:1005
#define GENERIC_WRITE
Definition: nt_native.h:90
static void test_BuildCommDCBA(const char *string, const TEST *ptest, int initial_value, const DCB *pexpected_dcb)
Definition: comm.c:543
static PVOID ptr
Definition: dispmode.c:27
#define ok(value,...)
static HANDLE PIO_APC_ROUTINE void PIO_STATUS_BLOCK void ULONG PLARGE_INTEGER offset
Definition: comm.c:54
static void test_GetModemStatus(HANDLE hcom)
Definition: comm.c:736
static void test_WaitRx(void)
Definition: comm.c:1329
HANDLE hEvent
Definition: winbase.h:792
static BOOL loopback_dtr_dcd
Definition: comm.c:52
#define MS_DSR_ON
Definition: winbase.h:511
#define LOOPBACK_DTR_DSR
Definition: comm.c:40
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:112
smooth NULL
Definition: ftsmooth.c:416
#define ERROR_NOT_READY
Definition: winerror.h:124
static void test_LoopbackRead(void)
Definition: comm.c:1023
static void test_LoopbackDtrDsr(void)
Definition: comm.c:1226
BOOL WINAPI GetCommState(HANDLE handle, LPDCB lpdcb)
Definition: comm.c:902
#define CE_MODE
Definition: winbase.h:139
#define STD_INPUT_HANDLE
Definition: winbase.h:264
BOOL WINAPI BuildCommDCBAndTimeoutsA(LPCSTR device, LPDCB lpdcb, LPCOMMTIMEOUTS lptimeouts)
Definition: comm.c:447
#define NOPARITY
Definition: winbase.h:434
#define OPEN_EXISTING
Definition: compat.h:426
BOOL WINAPI SetCommBreak(HANDLE handle)
Definition: comm.c:557
int64_t LONGLONG
Definition: typedefs.h:66
BOOL result
Definition: comm.c:67
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLsizeiptr size
Definition: glext.h:5919
#define LOOPBACK_CTS_RTS
Definition: comm.c:39
BOOL WINAPI FlushFileBuffers(IN HANDLE hFile)
Definition: fileinfo.c:175
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define STATUS_PENDING
Definition: ntstatus.h:82
#define TEST(x)
Definition: precomp.h:20
static BOOL loopback_txd_rxd
Definition: comm.c:48
COMMTIMEOUTS timeouts2
Definition: comm.c:70
#define WINAPI
Definition: msvc.h:8
#define LOOPBACK_DTR_DCD
Definition: comm.c:42
static NTSTATUS(WINAPI *pNtReadFile)(HANDLE hFile
PVOID HANDLE
Definition: typedefs.h:71
unsigned long DWORD
Definition: ntddk_ex.h:95
static void check_result(const char *function, const TEST *ptest, int initial_value, BOOL result)
Definition: comm.c:450
char string[100]
Definition: comm.c:66
#define success(from, fromstr, to, tostr)
#define SetLastError(x)
Definition: compat.h:409
BOOL WINAPI GetCommModemStatus(HANDLE hFile, LPDWORD lpModemStat)
Definition: comm.c:1097
static HANDLE test_OpenComm(BOOL doOverlap)
Definition: comm.c:689
#define WAIT_TIMEOUT
Definition: dderror.h:14
static void test_WaitRing(void)
Definition: comm.c:1683
static BOOL loopback_dtr_ring
Definition: comm.c:51
#define EV_RLSD
Definition: winbase.h:415
int ret
BOOL WINAPI ClearCommBreak(HANDLE handle)
Definition: comm.c:580
#define LOOPBACK_TXD_RXD
Definition: comm.c:38
Definition: stat.h:55
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
#define EV_TXEMPTY
Definition: winbase.h:419
#define GENERIC_READ
Definition: compat.h:124
__inline int after(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2419
#define err(...)
#define MS_CTS_ON
Definition: winbase.h:510
uint32_t DWORD_PTR
Definition: typedefs.h:63
_In_ HANDLE hFile
Definition: mswsock.h:90
#define comm
Definition: kernel32.h:11
#define broken(x)
Definition: _sntprintf.h:21
#define EV_DSR
Definition: winbase.h:409
Status
Definition: gdiplustypes.h:24
BOOL WINAPI EscapeCommFunction(HANDLE handle, DWORD func)
Definition: comm.c:602
#define CLRDTR
Definition: winbase.h:221
BOOL WINAPI BuildCommDCBW(LPCWSTR devid, LPDCB lpdcb)
Definition: comm.c:533
static void test_AbortWaitCts(void)
Definition: comm.c:1534
static void test_BuildCommDCB(void)
Definition: comm.c:635
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED * overlapped
Definition: sock.c:82
#define EV_RING
Definition: winbase.h:414
static void test_WaitDsr(void)
Definition: comm.c:1601
#define EV_BREAK
Definition: winbase.h:407
#define DTR_CONTROL_HANDSHAKE
Definition: winbase.h:516
#define check_dcb_member2(a, c, b)
Definition: comm.c:460
Definition: comm.c:64
BOOL WINAPI GetDefaultCommConfigA(LPCSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize)
Definition: comm.c:1434
unsigned int * PULONG
Definition: retypes.h:1
BOOL WINAPI BuildCommDCBA(LPCSTR device, LPDCB lpdcb)
Definition: comm.c:429
unsigned int UINT
Definition: ndis.h:50
#define MultiByteToWideChar
Definition: compat.h:100
#define SETDTR
Definition: winbase.h:223
#define skip(...)
static void test_ClearCommError(void)
Definition: comm.c:988
#define EV_CTS
Definition: winbase.h:408
GLuint res
Definition: glext.h:9613
static void test_BuildCommDCBAndTimeoutsW(const char *string, const TEST *ptest, int initial_value, const DCB *pexpected_dcb, const COMMTIMEOUTS *pexpected_timeouts)
Definition: comm.c:605
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
static void test_LoopbackDtrRing(void)
Definition: comm.c:1274
#define SETRTS
Definition: winbase.h:224
#define GetProcAddress(x, y)
Definition: compat.h:410
#define FASTBAUD
Definition: comm.c:32
BOOL WINAPI WaitCommEvent(HANDLE hFile, LPDWORD lpdwEvents, LPOVERLAPPED lpOverlapped)
Definition: comm.c:1121
struct timeout * timeouts
Definition: dispatch.c:53
DCB dcb2
Definition: comm.c:69
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:399
static void test_waittxempty(void)
Definition: comm.c:790
static HANDLE PIO_APC_ROUTINE void PIO_STATUS_BLOCK void * buffer
Definition: comm.c:54
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
static void test_ReadTimeOut(void)
Definition: comm.c:749
return STATUS_SUCCESS
Definition: btrfs.c:2725
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:389
USHORT port
Definition: uri.c:227
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
static SERVICE_STATUS status
Definition: service.c:31
#define SLOWBAUD
Definition: comm.c:31
#define win_skip
Definition: test.h:141
#define MS_RING_ON
Definition: winbase.h:512
static void test_WaitDcd(void)
Definition: comm.c:1770
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define check_dcb_member(a, b)
Definition: comm.c:459
static void check_dcb(const char *function, const TEST *ptest, int initial_value, const DCB *pdcb1, const DCB *pdcb2)
Definition: comm.c:462
static void test_BuildCommDCBW(const char *string, const TEST *ptest, int initial_value, const DCB *pexpected_dcb)
Definition: comm.c:578
Definition: ps.c:97
static DWORD CALLBACK reset_CommMask(LPVOID arg)
Definition: comm.c:1516