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