xref: /reactos/dll/win32/kernel32/wine/comm.c (revision 2d4d5b63)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * DEC 93 Erik Bos <erik@xs4all.nl>
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 1996 Marcus Meissner
5c2c66affSColin Finck  *
6c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck  * License as published by the Free Software Foundation; either
9c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck  *
11c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14c2c66affSColin Finck  * Lesser General Public License for more details.
15c2c66affSColin Finck  *
16c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck  */
20c2c66affSColin Finck 
21c2c66affSColin Finck #include <k32.h>
22c2c66affSColin Finck 
23c2c66affSColin Finck typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
24c2c66affSColin Finck #undef SERIAL_LSRMST_ESCAPE
25c2c66affSColin Finck #undef SERIAL_LSRMST_LSR_DATA
26c2c66affSColin Finck #undef SERIAL_LSRMST_LSR_NODATA
27c2c66affSColin Finck #undef SERIAL_LSRMST_MST
28c2c66affSColin Finck #undef SERIAL_IOC_FCR_FIFO_ENABLE
29c2c66affSColin Finck #undef SERIAL_IOC_FCR_RCVR_RESET
30c2c66affSColin Finck #undef SERIAL_IOC_FCR_XMIT_RESET
31c2c66affSColin Finck #undef SERIAL_IOC_FCR_DMA_MODE
32c2c66affSColin Finck #undef SERIAL_IOC_FCR_RES1
33c2c66affSColin Finck #undef SERIAL_IOC_FCR_RES2
34c2c66affSColin Finck #undef SERIAL_IOC_FCR_RCVR_TRIGGER_LSB
35c2c66affSColin Finck #undef SERIAL_IOC_FCR_RCVR_TRIGGER_MSB
36c2c66affSColin Finck #undef SERIAL_IOC_MCR_DTR
37c2c66affSColin Finck #undef SERIAL_IOC_MCR_RTS
38c2c66affSColin Finck #undef SERIAL_IOC_MCR_OUT1
39c2c66affSColin Finck #undef SERIAL_IOC_MCR_OUT2
40c2c66affSColin Finck #undef SERIAL_IOC_MCR_LOOP
41c2c66affSColin Finck #undef IOCTL_SERIAL_LSRMST_INSERT
42c2c66affSColin Finck #include <ntddser.h>
43c2c66affSColin Finck 
44c2c66affSColin Finck #define NDEBUG
45c2c66affSColin Finck #include <debug.h>
46c2c66affSColin Finck DEBUG_CHANNEL(comm);
47c2c66affSColin Finck 
48c2c66affSColin Finck /***********************************************************************
49c2c66affSColin Finck  *           COMM_Parse*   (Internal)
50c2c66affSColin Finck  *
51c2c66affSColin Finck  *  The following COMM_Parse* functions are used by the BuildCommDCB
52c2c66affSColin Finck  *  functions to help parse the various parts of the device control string.
53c2c66affSColin Finck  */
COMM_ParseStart(LPCWSTR ptr)54c2c66affSColin Finck static LPCWSTR COMM_ParseStart(LPCWSTR ptr)
55c2c66affSColin Finck {
56c2c66affSColin Finck 	static const WCHAR comW[] = {'C','O','M',0};
57c2c66affSColin Finck 
58c2c66affSColin Finck 	/* The device control string may optionally start with "COMx" followed
59c2c66affSColin Finck 	   by an optional ':' and spaces. */
60c2c66affSColin Finck 	if(!strncmpiW(ptr, comW, 3))
61c2c66affSColin Finck 	{
62c2c66affSColin Finck 		ptr += 3;
63c2c66affSColin Finck 
64c2c66affSColin Finck 		/* Allow any com port above 0 as Win 9x does (NT only allows
65c2c66affSColin Finck 		   values for com ports which are actually present) */
66c2c66affSColin Finck 		if(*ptr < '1' || *ptr > '9')
67c2c66affSColin Finck 			return NULL;
68c2c66affSColin Finck 
69c2c66affSColin Finck 		/* Advance pointer past port number */
70c2c66affSColin Finck 		while(*ptr >= '0' && *ptr <= '9') ptr++;
71c2c66affSColin Finck 
72c2c66affSColin Finck 		/* The com port number must be followed by a ':' or ' ' */
73c2c66affSColin Finck 		if(*ptr != ':' && *ptr != ' ')
74c2c66affSColin Finck 			return NULL;
75c2c66affSColin Finck 
76c2c66affSColin Finck 		/* Advance pointer to beginning of next parameter */
77c2c66affSColin Finck 		while(*ptr == ' ') ptr++;
78c2c66affSColin Finck 		if(*ptr == ':')
79c2c66affSColin Finck 		{
80c2c66affSColin Finck 			ptr++;
81c2c66affSColin Finck 			while(*ptr == ' ') ptr++;
82c2c66affSColin Finck 		}
83c2c66affSColin Finck 	}
84c2c66affSColin Finck 	/* The device control string must not start with a space. */
85c2c66affSColin Finck 	else if(*ptr == ' ')
86c2c66affSColin Finck 		return NULL;
87c2c66affSColin Finck 
88c2c66affSColin Finck 	return ptr;
89c2c66affSColin Finck }
90c2c66affSColin Finck 
COMM_ParseNumber(LPCWSTR ptr,LPDWORD lpnumber)91c2c66affSColin Finck static LPCWSTR COMM_ParseNumber(LPCWSTR ptr, LPDWORD lpnumber)
92c2c66affSColin Finck {
93c2c66affSColin Finck 	if(*ptr < '0' || *ptr > '9') return NULL;
94c2c66affSColin Finck 	*lpnumber = strtoulW(ptr, NULL, 10);
95c2c66affSColin Finck 	while(*ptr >= '0' && *ptr <= '9') ptr++;
96c2c66affSColin Finck 	return ptr;
97c2c66affSColin Finck }
98c2c66affSColin Finck 
COMM_ParseParity(LPCWSTR ptr,LPBYTE lpparity)99c2c66affSColin Finck static LPCWSTR COMM_ParseParity(LPCWSTR ptr, LPBYTE lpparity)
100c2c66affSColin Finck {
101c2c66affSColin Finck 	/* Contrary to what you might expect, Windows only sets the Parity
102c2c66affSColin Finck 	   member of DCB and not fParity even when parity is specified in the
103c2c66affSColin Finck 	   device control string */
104c2c66affSColin Finck 
105c2c66affSColin Finck 	switch(toupperW(*ptr++))
106c2c66affSColin Finck 	{
107c2c66affSColin Finck 	case 'E':
108c2c66affSColin Finck 		*lpparity = EVENPARITY;
109c2c66affSColin Finck 		break;
110c2c66affSColin Finck 	case 'M':
111c2c66affSColin Finck 		*lpparity = MARKPARITY;
112c2c66affSColin Finck 		break;
113c2c66affSColin Finck 	case 'N':
114c2c66affSColin Finck 		*lpparity = NOPARITY;
115c2c66affSColin Finck 		break;
116c2c66affSColin Finck 	case 'O':
117c2c66affSColin Finck 		*lpparity = ODDPARITY;
118c2c66affSColin Finck 		break;
119c2c66affSColin Finck 	case 'S':
120c2c66affSColin Finck 		*lpparity = SPACEPARITY;
121c2c66affSColin Finck 		break;
122c2c66affSColin Finck 	default:
123c2c66affSColin Finck 		return NULL;
124c2c66affSColin Finck 	}
125c2c66affSColin Finck 
126c2c66affSColin Finck 	return ptr;
127c2c66affSColin Finck }
128c2c66affSColin Finck 
COMM_ParseByteSize(LPCWSTR ptr,LPBYTE lpbytesize)129c2c66affSColin Finck static LPCWSTR COMM_ParseByteSize(LPCWSTR ptr, LPBYTE lpbytesize)
130c2c66affSColin Finck {
131c2c66affSColin Finck 	DWORD temp;
132c2c66affSColin Finck 
133c2c66affSColin Finck 	if(!(ptr = COMM_ParseNumber(ptr, &temp)))
134c2c66affSColin Finck 		return NULL;
135c2c66affSColin Finck 
136c2c66affSColin Finck 	if(temp >= 5 && temp <= 8)
137c2c66affSColin Finck 	{
138c2c66affSColin Finck 		*lpbytesize = temp;
139c2c66affSColin Finck 		return ptr;
140c2c66affSColin Finck 	}
141c2c66affSColin Finck 	else
142c2c66affSColin Finck 		return NULL;
143c2c66affSColin Finck }
144c2c66affSColin Finck 
COMM_ParseStopBits(LPCWSTR ptr,LPBYTE lpstopbits)145c2c66affSColin Finck static LPCWSTR COMM_ParseStopBits(LPCWSTR ptr, LPBYTE lpstopbits)
146c2c66affSColin Finck {
147c2c66affSColin Finck 	DWORD temp;
148c2c66affSColin Finck 	static const WCHAR stopbits15W[] = {'1','.','5',0};
149c2c66affSColin Finck 
150c2c66affSColin Finck 	if(!strncmpW(stopbits15W, ptr, 3))
151c2c66affSColin Finck 	{
152c2c66affSColin Finck 		ptr += 3;
153c2c66affSColin Finck 		*lpstopbits = ONE5STOPBITS;
154c2c66affSColin Finck 	}
155c2c66affSColin Finck 	else
156c2c66affSColin Finck 	{
157c2c66affSColin Finck 		if(!(ptr = COMM_ParseNumber(ptr, &temp)))
158c2c66affSColin Finck 			return NULL;
159c2c66affSColin Finck 
160c2c66affSColin Finck 		if(temp == 1)
161c2c66affSColin Finck 			*lpstopbits = ONESTOPBIT;
162c2c66affSColin Finck 		else if(temp == 2)
163c2c66affSColin Finck 			*lpstopbits = TWOSTOPBITS;
164c2c66affSColin Finck 		else
165c2c66affSColin Finck 			return NULL;
166c2c66affSColin Finck 	}
167c2c66affSColin Finck 
168c2c66affSColin Finck 	return ptr;
169c2c66affSColin Finck }
170c2c66affSColin Finck 
COMM_ParseOnOff(LPCWSTR ptr,LPDWORD lponoff)171c2c66affSColin Finck static LPCWSTR COMM_ParseOnOff(LPCWSTR ptr, LPDWORD lponoff)
172c2c66affSColin Finck {
173c2c66affSColin Finck 	static const WCHAR onW[] = {'o','n',0};
174c2c66affSColin Finck 	static const WCHAR offW[] = {'o','f','f',0};
175c2c66affSColin Finck 
176c2c66affSColin Finck 	if(!strncmpiW(onW, ptr, 2))
177c2c66affSColin Finck 	{
178c2c66affSColin Finck 		ptr += 2;
179c2c66affSColin Finck 		*lponoff = 1;
180c2c66affSColin Finck 	}
181c2c66affSColin Finck 	else if(!strncmpiW(offW, ptr, 3))
182c2c66affSColin Finck 	{
183c2c66affSColin Finck 		ptr += 3;
184c2c66affSColin Finck 		*lponoff = 0;
185c2c66affSColin Finck 	}
186c2c66affSColin Finck 	else
187c2c66affSColin Finck 		return NULL;
188c2c66affSColin Finck 
189c2c66affSColin Finck 	return ptr;
190c2c66affSColin Finck }
191c2c66affSColin Finck 
192c2c66affSColin Finck /***********************************************************************
193c2c66affSColin Finck  *           COMM_BuildOldCommDCB   (Internal)
194c2c66affSColin Finck  *
195c2c66affSColin Finck  *  Build a DCB using the old style settings string eg: "96,n,8,1"
196c2c66affSColin Finck  */
COMM_BuildOldCommDCB(LPCWSTR device,LPDCB lpdcb)197c2c66affSColin Finck static BOOL COMM_BuildOldCommDCB(LPCWSTR device, LPDCB lpdcb)
198c2c66affSColin Finck {
199c2c66affSColin Finck 	WCHAR last = 0;
200c2c66affSColin Finck 
201c2c66affSColin Finck 	if(!(device = COMM_ParseNumber(device, &lpdcb->BaudRate)))
202c2c66affSColin Finck 		return FALSE;
203c2c66affSColin Finck 
204c2c66affSColin Finck 	switch(lpdcb->BaudRate)
205c2c66affSColin Finck 	{
206c2c66affSColin Finck 	case 11:
207c2c66affSColin Finck 	case 30:
208c2c66affSColin Finck 	case 60:
209c2c66affSColin Finck 		lpdcb->BaudRate *= 10;
210c2c66affSColin Finck 		break;
211c2c66affSColin Finck 	case 12:
212c2c66affSColin Finck 	case 24:
213c2c66affSColin Finck 	case 48:
214c2c66affSColin Finck 	case 96:
215c2c66affSColin Finck 		lpdcb->BaudRate *= 100;
216c2c66affSColin Finck 		break;
217c2c66affSColin Finck 	case 19:
218c2c66affSColin Finck 		lpdcb->BaudRate = 19200;
219c2c66affSColin Finck 		break;
220c2c66affSColin Finck 	}
221c2c66affSColin Finck 
222c2c66affSColin Finck 	while(*device == ' ') device++;
223c2c66affSColin Finck 	if(*device++ != ',') return FALSE;
224c2c66affSColin Finck 	while(*device == ' ') device++;
225c2c66affSColin Finck 
226c2c66affSColin Finck 	if(!(device = COMM_ParseParity(device, &lpdcb->Parity)))
227c2c66affSColin Finck 		return FALSE;
228c2c66affSColin Finck 
229c2c66affSColin Finck 	while(*device == ' ') device++;
230c2c66affSColin Finck 	if(*device++ != ',') return FALSE;
231c2c66affSColin Finck 	while(*device == ' ') device++;
232c2c66affSColin Finck 
233c2c66affSColin Finck 	if(!(device = COMM_ParseByteSize(device, &lpdcb->ByteSize)))
234c2c66affSColin Finck 		return FALSE;
235c2c66affSColin Finck 
236c2c66affSColin Finck 	while(*device == ' ') device++;
237c2c66affSColin Finck 	if(*device++ != ',') return FALSE;
238c2c66affSColin Finck 	while(*device == ' ') device++;
239c2c66affSColin Finck 
240c2c66affSColin Finck 	if(!(device = COMM_ParseStopBits(device, &lpdcb->StopBits)))
241c2c66affSColin Finck 		return FALSE;
242c2c66affSColin Finck 
243c2c66affSColin Finck 	/* The last parameter for flow control is optional. */
244c2c66affSColin Finck 	while(*device == ' ') device++;
245c2c66affSColin Finck 	if(*device == ',')
246c2c66affSColin Finck 	{
247c2c66affSColin Finck 		device++;
248c2c66affSColin Finck 		while(*device == ' ') device++;
249c2c66affSColin Finck 		if(*device) last = toupperW(*device++);
250c2c66affSColin Finck 		while(*device == ' ') device++;
251c2c66affSColin Finck 	}
252c2c66affSColin Finck 
253c2c66affSColin Finck 	/* Win NT sets the flow control members based on (or lack of) the last
254c2c66affSColin Finck 	   parameter.  Win 9x does not set these members. */
255c2c66affSColin Finck 	switch(last)
256c2c66affSColin Finck 	{
257c2c66affSColin Finck 	case 0:
258c2c66affSColin Finck 		lpdcb->fInX = FALSE;
259c2c66affSColin Finck 		lpdcb->fOutX = FALSE;
260c2c66affSColin Finck 		lpdcb->fOutxCtsFlow = FALSE;
261c2c66affSColin Finck 		lpdcb->fOutxDsrFlow = FALSE;
262c2c66affSColin Finck 		lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
263c2c66affSColin Finck 		lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
264c2c66affSColin Finck 		break;
265c2c66affSColin Finck 	case 'X':
266c2c66affSColin Finck 		lpdcb->fInX = TRUE;
267c2c66affSColin Finck 		lpdcb->fOutX = TRUE;
268c2c66affSColin Finck 		lpdcb->fOutxCtsFlow = FALSE;
269c2c66affSColin Finck 		lpdcb->fOutxDsrFlow = FALSE;
270c2c66affSColin Finck 		lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
271c2c66affSColin Finck 		lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
272c2c66affSColin Finck 		break;
273c2c66affSColin Finck 	case 'P':
274c2c66affSColin Finck 		lpdcb->fInX = FALSE;
275c2c66affSColin Finck 		lpdcb->fOutX = FALSE;
276c2c66affSColin Finck 		lpdcb->fOutxCtsFlow = TRUE;
277c2c66affSColin Finck 		lpdcb->fOutxDsrFlow = TRUE;
278c2c66affSColin Finck 		lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
279c2c66affSColin Finck 		lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
280c2c66affSColin Finck 		break;
281c2c66affSColin Finck 	default:
282c2c66affSColin Finck 		return FALSE;
283c2c66affSColin Finck 	}
284c2c66affSColin Finck 
285c2c66affSColin Finck 	/* This should be the end of the string. */
286c2c66affSColin Finck 	if(*device) return FALSE;
287c2c66affSColin Finck 
288c2c66affSColin Finck 	return TRUE;
289c2c66affSColin Finck }
290c2c66affSColin Finck 
291c2c66affSColin Finck /***********************************************************************
292c2c66affSColin Finck  *           COMM_BuildNewCommDCB   (Internal)
293c2c66affSColin Finck  *
294c2c66affSColin Finck  *  Build a DCB using the new style settings string.
295c2c66affSColin Finck  *   eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on"
296c2c66affSColin Finck  */
COMM_BuildNewCommDCB(LPCWSTR device,LPDCB lpdcb,LPCOMMTIMEOUTS lptimeouts)297c2c66affSColin Finck static BOOL COMM_BuildNewCommDCB(LPCWSTR device, LPDCB lpdcb, LPCOMMTIMEOUTS lptimeouts)
298c2c66affSColin Finck {
299c2c66affSColin Finck 	DWORD temp;
300c2c66affSColin Finck 	BOOL baud = FALSE, stop = FALSE;
301c2c66affSColin Finck 	static const WCHAR baudW[] = {'b','a','u','d','=',0};
302c2c66affSColin Finck 	static const WCHAR parityW[] = {'p','a','r','i','t','y','=',0};
303c2c66affSColin Finck 	static const WCHAR dataW[] = {'d','a','t','a','=',0};
304c2c66affSColin Finck 	static const WCHAR stopW[] = {'s','t','o','p','=',0};
305c2c66affSColin Finck 	static const WCHAR toW[] = {'t','o','=',0};
306c2c66affSColin Finck 	static const WCHAR xonW[] = {'x','o','n','=',0};
307c2c66affSColin Finck 	static const WCHAR odsrW[] = {'o','d','s','r','=',0};
308c2c66affSColin Finck 	static const WCHAR octsW[] = {'o','c','t','s','=',0};
309c2c66affSColin Finck 	static const WCHAR dtrW[] = {'d','t','r','=',0};
310c2c66affSColin Finck 	static const WCHAR rtsW[] = {'r','t','s','=',0};
311c2c66affSColin Finck 	static const WCHAR idsrW[] = {'i','d','s','r','=',0};
312c2c66affSColin Finck 
313c2c66affSColin Finck 	while(*device)
314c2c66affSColin Finck 	{
315c2c66affSColin Finck 		while(*device == ' ') device++;
316c2c66affSColin Finck 
317c2c66affSColin Finck 		if(!strncmpiW(baudW, device, 5))
318c2c66affSColin Finck 		{
319c2c66affSColin Finck 			baud = TRUE;
320c2c66affSColin Finck 
321c2c66affSColin Finck 			if(!(device = COMM_ParseNumber(device + 5, &lpdcb->BaudRate)))
322c2c66affSColin Finck 				return FALSE;
323c2c66affSColin Finck 		}
324c2c66affSColin Finck 		else if(!strncmpiW(parityW, device, 7))
325c2c66affSColin Finck 		{
326c2c66affSColin Finck 			if(!(device = COMM_ParseParity(device + 7, &lpdcb->Parity)))
327c2c66affSColin Finck 				return FALSE;
328c2c66affSColin Finck 		}
329c2c66affSColin Finck 		else if(!strncmpiW(dataW, device, 5))
330c2c66affSColin Finck 		{
331c2c66affSColin Finck 			if(!(device = COMM_ParseByteSize(device + 5, &lpdcb->ByteSize)))
332c2c66affSColin Finck 				return FALSE;
333c2c66affSColin Finck 		}
334c2c66affSColin Finck 		else if(!strncmpiW(stopW, device, 5))
335c2c66affSColin Finck 		{
336c2c66affSColin Finck 			stop = TRUE;
337c2c66affSColin Finck 
338c2c66affSColin Finck 			if(!(device = COMM_ParseStopBits(device + 5, &lpdcb->StopBits)))
339c2c66affSColin Finck 				return FALSE;
340c2c66affSColin Finck 		}
341c2c66affSColin Finck 		else if(!strncmpiW(toW, device, 3))
342c2c66affSColin Finck 		{
343c2c66affSColin Finck 			if(!(device = COMM_ParseOnOff(device + 3, &temp)))
344c2c66affSColin Finck 				return FALSE;
345c2c66affSColin Finck 
346c2c66affSColin Finck 			lptimeouts->ReadIntervalTimeout = 0;
347c2c66affSColin Finck 			lptimeouts->ReadTotalTimeoutMultiplier = 0;
348c2c66affSColin Finck 			lptimeouts->ReadTotalTimeoutConstant = 0;
349c2c66affSColin Finck 			lptimeouts->WriteTotalTimeoutMultiplier = 0;
350c2c66affSColin Finck 			lptimeouts->WriteTotalTimeoutConstant = temp ? 60000 : 0;
351c2c66affSColin Finck 		}
352c2c66affSColin Finck 		else if(!strncmpiW(xonW, device, 4))
353c2c66affSColin Finck 		{
354c2c66affSColin Finck 			if(!(device = COMM_ParseOnOff(device + 4, &temp)))
355c2c66affSColin Finck 				return FALSE;
356c2c66affSColin Finck 
357c2c66affSColin Finck 			lpdcb->fOutX = temp;
358c2c66affSColin Finck 			lpdcb->fInX = temp;
359c2c66affSColin Finck 		}
360c2c66affSColin Finck 		else if(!strncmpiW(odsrW, device, 5))
361c2c66affSColin Finck 		{
362c2c66affSColin Finck 			if(!(device = COMM_ParseOnOff(device + 5, &temp)))
363c2c66affSColin Finck 				return FALSE;
364c2c66affSColin Finck 
365c2c66affSColin Finck 			lpdcb->fOutxDsrFlow = temp;
366c2c66affSColin Finck 		}
367c2c66affSColin Finck 		else if(!strncmpiW(octsW, device, 5))
368c2c66affSColin Finck 		{
369c2c66affSColin Finck 			if(!(device = COMM_ParseOnOff(device + 5, &temp)))
370c2c66affSColin Finck 				return FALSE;
371c2c66affSColin Finck 
372c2c66affSColin Finck 			lpdcb->fOutxCtsFlow = temp;
373c2c66affSColin Finck 		}
374c2c66affSColin Finck 		else if(!strncmpiW(dtrW, device, 4))
375c2c66affSColin Finck 		{
376c2c66affSColin Finck 			if(!(device = COMM_ParseOnOff(device + 4, &temp)))
377c2c66affSColin Finck 				return FALSE;
378c2c66affSColin Finck 
379c2c66affSColin Finck 			lpdcb->fDtrControl = temp;
380c2c66affSColin Finck 		}
381c2c66affSColin Finck 		else if(!strncmpiW(rtsW, device, 4))
382c2c66affSColin Finck 		{
383c2c66affSColin Finck 			if(!(device = COMM_ParseOnOff(device + 4, &temp)))
384c2c66affSColin Finck 				return FALSE;
385c2c66affSColin Finck 
386c2c66affSColin Finck 			lpdcb->fRtsControl = temp;
387c2c66affSColin Finck 		}
388c2c66affSColin Finck 		else if(!strncmpiW(idsrW, device, 5))
389c2c66affSColin Finck 		{
390c2c66affSColin Finck 			if(!(device = COMM_ParseOnOff(device + 5, &temp)))
391c2c66affSColin Finck 				return FALSE;
392c2c66affSColin Finck 
393c2c66affSColin Finck 			/* Win NT sets the fDsrSensitivity member based on the
394c2c66affSColin Finck 			   idsr parameter.  Win 9x sets fOutxDsrFlow instead. */
395c2c66affSColin Finck 			lpdcb->fDsrSensitivity = temp;
396c2c66affSColin Finck 		}
397c2c66affSColin Finck 		else
398c2c66affSColin Finck 			return FALSE;
399c2c66affSColin Finck 
400c2c66affSColin Finck 		/* After the above parsing, the next character (if not the end of
401c2c66affSColin Finck 		   the string) should be a space */
402c2c66affSColin Finck 		if(*device && *device != ' ')
403c2c66affSColin Finck 			return FALSE;
404c2c66affSColin Finck 	}
405c2c66affSColin Finck 
406c2c66affSColin Finck 	/* If stop bits were not specified, a default is always supplied. */
407c2c66affSColin Finck 	if(!stop)
408c2c66affSColin Finck 	{
409c2c66affSColin Finck 		if(baud && lpdcb->BaudRate == 110)
410c2c66affSColin Finck 			lpdcb->StopBits = TWOSTOPBITS;
411c2c66affSColin Finck 		else
412c2c66affSColin Finck 			lpdcb->StopBits = ONESTOPBIT;
413c2c66affSColin Finck 	}
414c2c66affSColin Finck 
415c2c66affSColin Finck 	return TRUE;
416c2c66affSColin Finck }
417c2c66affSColin Finck 
418c2c66affSColin Finck /**************************************************************************
419c2c66affSColin Finck  *         BuildCommDCBA		(KERNEL32.@)
420c2c66affSColin Finck  *
421c2c66affSColin Finck  *  Updates a device control block data structure with values from an
422c2c66affSColin Finck  *  ascii device control string.  The device control string has two forms
423c2c66affSColin Finck  *  normal and extended, it must be exclusively in one or the other form.
424c2c66affSColin Finck  *
425c2c66affSColin Finck  * RETURNS
426c2c66affSColin Finck  *
427c2c66affSColin Finck  *  True on success, false on a malformed control string.
428c2c66affSColin Finck  */
BuildCommDCBA(LPCSTR device,LPDCB lpdcb)429c2c66affSColin Finck BOOL WINAPI BuildCommDCBA(
430c2c66affSColin Finck     LPCSTR device, /* [in] The ascii device control string used to update the DCB. */
431c2c66affSColin Finck     LPDCB  lpdcb)  /* [out] The device control block to be updated. */
432c2c66affSColin Finck {
433c2c66affSColin Finck 	return BuildCommDCBAndTimeoutsA(device,lpdcb,NULL);
434c2c66affSColin Finck }
435c2c66affSColin Finck 
436c2c66affSColin Finck /**************************************************************************
437c2c66affSColin Finck  *         BuildCommDCBAndTimeoutsA		(KERNEL32.@)
438c2c66affSColin Finck  *
439c2c66affSColin Finck  *  Updates a device control block data structure with values from an
440c2c66affSColin Finck  *  ascii device control string.  Taking timeout values from a timeouts
441c2c66affSColin Finck  *  struct if desired by the control string.
442c2c66affSColin Finck  *
443c2c66affSColin Finck  * RETURNS
444c2c66affSColin Finck  *
445c2c66affSColin Finck  *  True on success, false bad handles etc.
446c2c66affSColin Finck  */
BuildCommDCBAndTimeoutsA(LPCSTR device,LPDCB lpdcb,LPCOMMTIMEOUTS lptimeouts)447c2c66affSColin Finck BOOL WINAPI BuildCommDCBAndTimeoutsA(
448c2c66affSColin Finck     LPCSTR         device,     /* [in] The ascii device control string. */
449c2c66affSColin Finck     LPDCB          lpdcb,      /* [out] The device control block to be updated. */
450c2c66affSColin Finck     LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */
451c2c66affSColin Finck {
452c2c66affSColin Finck 	BOOL ret = FALSE;
453c2c66affSColin Finck 	UNICODE_STRING deviceW;
454c2c66affSColin Finck 
455c2c66affSColin Finck 	TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
456c2c66affSColin Finck 	if(device) RtlCreateUnicodeStringFromAsciiz(&deviceW,device);
457c2c66affSColin Finck 	else deviceW.Buffer = NULL;
458c2c66affSColin Finck 
459c2c66affSColin Finck 	if(deviceW.Buffer) ret = BuildCommDCBAndTimeoutsW(deviceW.Buffer,lpdcb,lptimeouts);
460c2c66affSColin Finck 
461c2c66affSColin Finck 	RtlFreeUnicodeString(&deviceW);
462c2c66affSColin Finck 	return ret;
463c2c66affSColin Finck }
464c2c66affSColin Finck 
465c2c66affSColin Finck /**************************************************************************
466c2c66affSColin Finck  *         BuildCommDCBAndTimeoutsW	(KERNEL32.@)
467c2c66affSColin Finck  *
468c2c66affSColin Finck  *  Updates a device control block data structure with values from a
469c2c66affSColin Finck  *  unicode device control string.  Taking timeout values from a timeouts
470c2c66affSColin Finck  *  struct if desired by the control string.
471c2c66affSColin Finck  *
472c2c66affSColin Finck  * RETURNS
473c2c66affSColin Finck  *
474c2c66affSColin Finck  *  True on success, false bad handles etc
475c2c66affSColin Finck  */
BuildCommDCBAndTimeoutsW(LPCWSTR devid,LPDCB lpdcb,LPCOMMTIMEOUTS lptimeouts)476c2c66affSColin Finck BOOL WINAPI BuildCommDCBAndTimeoutsW(
477c2c66affSColin Finck     LPCWSTR        devid,      /* [in] The unicode device control string. */
478c2c66affSColin Finck     LPDCB          lpdcb,      /* [out] The device control block to be updated. */
479c2c66affSColin Finck     LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */
480c2c66affSColin Finck {
481c2c66affSColin Finck 	DCB dcb;
482c2c66affSColin Finck 	COMMTIMEOUTS timeouts;
483c2c66affSColin Finck 	BOOL result;
484c2c66affSColin Finck 	LPCWSTR ptr = devid;
485c2c66affSColin Finck 
486c2c66affSColin Finck 	TRACE("(%s,%p,%p)\n",debugstr_w(devid),lpdcb,lptimeouts);
487c2c66affSColin Finck 
488c2c66affSColin Finck 	memset(&timeouts, 0, sizeof timeouts);
489c2c66affSColin Finck 
490c2c66affSColin Finck 	/* Set DCBlength. (Windows NT does not do this, but 9x does) */
491c2c66affSColin Finck 	lpdcb->DCBlength = sizeof(DCB);
492c2c66affSColin Finck 
493c2c66affSColin Finck 	/* Make a copy of the original data structures to work with since if
494c2c66affSColin Finck 	   if there is an error in the device control string the originals
495c2c66affSColin Finck 	   should not be modified (except possibly DCBlength) */
496c2c66affSColin Finck 	dcb = *lpdcb;
497c2c66affSColin Finck 	if(lptimeouts) timeouts = *lptimeouts;
498c2c66affSColin Finck 
499c2c66affSColin Finck 	ptr = COMM_ParseStart(ptr);
500c2c66affSColin Finck 
501c2c66affSColin Finck 	if(ptr == NULL)
502c2c66affSColin Finck 		result = FALSE;
503c2c66affSColin Finck 	else if(strchrW(ptr, ','))
504c2c66affSColin Finck 		result = COMM_BuildOldCommDCB(ptr, &dcb);
505c2c66affSColin Finck 	else
506c2c66affSColin Finck 		result = COMM_BuildNewCommDCB(ptr, &dcb, &timeouts);
507c2c66affSColin Finck 
508c2c66affSColin Finck 	if(result)
509c2c66affSColin Finck 	{
510c2c66affSColin Finck 		*lpdcb = dcb;
511c2c66affSColin Finck 		if(lptimeouts) *lptimeouts = timeouts;
512c2c66affSColin Finck 		return TRUE;
513c2c66affSColin Finck 	}
514c2c66affSColin Finck 	else
515c2c66affSColin Finck 	{
516c2c66affSColin Finck 		WARN("Invalid device control string: %s\n", debugstr_w(devid));
517c2c66affSColin Finck 		SetLastError(ERROR_INVALID_PARAMETER);
518c2c66affSColin Finck 		return FALSE;
519c2c66affSColin Finck 	}
520c2c66affSColin Finck }
521c2c66affSColin Finck 
522c2c66affSColin Finck /**************************************************************************
523c2c66affSColin Finck  *         BuildCommDCBW		(KERNEL32.@)
524c2c66affSColin Finck  *
525c2c66affSColin Finck  *  Updates a device control block structure with values from an
526c2c66affSColin Finck  *  unicode device control string.  The device control string has two forms
527c2c66affSColin Finck  *  normal and extended, it must be exclusively in one or the other form.
528c2c66affSColin Finck  *
529c2c66affSColin Finck  * RETURNS
530c2c66affSColin Finck  *
531c2c66affSColin Finck  *  True on success, false on a malformed control string.
532c2c66affSColin Finck  */
BuildCommDCBW(LPCWSTR devid,LPDCB lpdcb)533c2c66affSColin Finck BOOL WINAPI BuildCommDCBW(
534c2c66affSColin Finck     LPCWSTR devid, /* [in] The unicode device control string. */
535c2c66affSColin Finck     LPDCB   lpdcb) /* [out] The device control block to be updated. */
536c2c66affSColin Finck {
537c2c66affSColin Finck 	return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL);
538c2c66affSColin Finck }
539c2c66affSColin Finck 
540c2c66affSColin Finck /*****************************************************************************
541c2c66affSColin Finck  *	SetCommBreak		(KERNEL32.@)
542c2c66affSColin Finck  *
543c2c66affSColin Finck  *  Halts the transmission of characters to a communications device.
544c2c66affSColin Finck  *
545c2c66affSColin Finck  * PARAMS
546c2c66affSColin Finck  *      handle  [in] The communications device to suspend
547c2c66affSColin Finck  *
548c2c66affSColin Finck  * RETURNS
549c2c66affSColin Finck  *
550c2c66affSColin Finck  *  True on success, and false if the communications device could not be found,
551c2c66affSColin Finck  *  the control is not supported.
552c2c66affSColin Finck  *
553c2c66affSColin Finck  * BUGS
554c2c66affSColin Finck  *
555c2c66affSColin Finck  *  Only TIOCSBRK and TIOCCBRK are supported.
556c2c66affSColin Finck  */
SetCommBreak(HANDLE handle)557c2c66affSColin Finck BOOL WINAPI SetCommBreak(HANDLE handle)
558c2c66affSColin Finck {
559c2c66affSColin Finck     DWORD dwBytesReturned;
560c2c66affSColin Finck     return DeviceIoControl(handle, IOCTL_SERIAL_SET_BREAK_ON, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
561c2c66affSColin Finck }
562c2c66affSColin Finck 
563c2c66affSColin Finck /*****************************************************************************
564c2c66affSColin Finck  *	ClearCommBreak		(KERNEL32.@)
565c2c66affSColin Finck  *
566c2c66affSColin Finck  *  Resumes character transmission from a communication device.
567c2c66affSColin Finck  *
568c2c66affSColin Finck  * PARAMS
569c2c66affSColin Finck  *
570c2c66affSColin Finck  *      handle [in] The halted communication device whose character transmission is to be resumed
571c2c66affSColin Finck  *
572c2c66affSColin Finck  * RETURNS
573c2c66affSColin Finck  *
574c2c66affSColin Finck  *  True on success and false if the communications device could not be found.
575c2c66affSColin Finck  *
576c2c66affSColin Finck  * BUGS
577c2c66affSColin Finck  *
578c2c66affSColin Finck  *  Only TIOCSBRK and TIOCCBRK are supported.
579c2c66affSColin Finck  */
ClearCommBreak(HANDLE handle)580c2c66affSColin Finck BOOL WINAPI ClearCommBreak(HANDLE handle)
581c2c66affSColin Finck {
582c2c66affSColin Finck     DWORD dwBytesReturned;
583c2c66affSColin Finck     return DeviceIoControl(handle, IOCTL_SERIAL_SET_BREAK_OFF, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
584c2c66affSColin Finck }
585c2c66affSColin Finck 
586c2c66affSColin Finck /*****************************************************************************
587c2c66affSColin Finck  *	EscapeCommFunction	(KERNEL32.@)
588c2c66affSColin Finck  *
589c2c66affSColin Finck  *  Directs a communication device to perform an extended function.
590c2c66affSColin Finck  *
591c2c66affSColin Finck  * PARAMS
592c2c66affSColin Finck  *
593c2c66affSColin Finck  *      handle          [in] The communication device to perform the extended function
594c2c66affSColin Finck  *      nFunction       [in] The extended function to be performed
595c2c66affSColin Finck  *
596c2c66affSColin Finck  * RETURNS
597c2c66affSColin Finck  *
598c2c66affSColin Finck  *  True or requested data on successful completion of the command,
599c2c66affSColin Finck  *  false if the device is not present cannot execute the command
600c2c66affSColin Finck  *  or the command failed.
601c2c66affSColin Finck  */
EscapeCommFunction(HANDLE handle,DWORD func)602c2c66affSColin Finck BOOL WINAPI EscapeCommFunction(HANDLE handle, DWORD func)
603c2c66affSColin Finck {
604c2c66affSColin Finck     DWORD       ioc;
605c2c66affSColin Finck     DWORD dwBytesReturned;
606c2c66affSColin Finck 
607c2c66affSColin Finck     switch (func)
608c2c66affSColin Finck     {
609c2c66affSColin Finck     case CLRDTR:        ioc = IOCTL_SERIAL_CLR_DTR;             break;
610c2c66affSColin Finck     case CLRRTS:        ioc = IOCTL_SERIAL_CLR_RTS;             break;
611c2c66affSColin Finck     case SETDTR:        ioc = IOCTL_SERIAL_SET_DTR;             break;
612c2c66affSColin Finck     case SETRTS:        ioc = IOCTL_SERIAL_SET_RTS;             break;
613c2c66affSColin Finck     case SETXOFF:       ioc = IOCTL_SERIAL_SET_XOFF;            break;
614c2c66affSColin Finck     case SETXON:        ioc = IOCTL_SERIAL_SET_XON;             break;
615c2c66affSColin Finck     case SETBREAK:      ioc = IOCTL_SERIAL_SET_BREAK_ON;        break;
616c2c66affSColin Finck     case CLRBREAK:      ioc = IOCTL_SERIAL_SET_BREAK_OFF;       break;
617c2c66affSColin Finck     case RESETDEV:      ioc = IOCTL_SERIAL_RESET_DEVICE;        break;
618c2c66affSColin Finck     default:
619c2c66affSColin Finck         ERR("Unknown function code (%u)\n", func);
620c2c66affSColin Finck         SetLastError(ERROR_INVALID_PARAMETER);
621c2c66affSColin Finck         return FALSE;
622c2c66affSColin Finck     }
623c2c66affSColin Finck     return DeviceIoControl(handle, ioc, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
624c2c66affSColin Finck }
625c2c66affSColin Finck 
626c2c66affSColin Finck /********************************************************************
627c2c66affSColin Finck  *      PurgeComm        (KERNEL32.@)
628c2c66affSColin Finck  *
629c2c66affSColin Finck  *  Terminates pending operations and/or discards buffers on a
630c2c66affSColin Finck  *  communication resource.
631c2c66affSColin Finck  *
632c2c66affSColin Finck  * PARAMS
633c2c66affSColin Finck  *
634c2c66affSColin Finck  *      handle  [in] The communication resource to be purged
635c2c66affSColin Finck  *      flags   [in] Flags for clear pending/buffer on input/output
636c2c66affSColin Finck  *
637c2c66affSColin Finck  * RETURNS
638c2c66affSColin Finck  *
639c2c66affSColin Finck  *  True on success and false if the communications handle is bad.
640c2c66affSColin Finck  */
PurgeComm(HANDLE handle,DWORD flags)641c2c66affSColin Finck BOOL WINAPI PurgeComm(HANDLE handle, DWORD flags)
642c2c66affSColin Finck {
643c2c66affSColin Finck     DWORD dwBytesReturned;
644c2c66affSColin Finck     return DeviceIoControl(handle, IOCTL_SERIAL_PURGE, &flags, sizeof(flags),
645c2c66affSColin Finck                            NULL, 0, &dwBytesReturned, NULL);
646c2c66affSColin Finck }
647c2c66affSColin Finck 
648c2c66affSColin Finck /*****************************************************************************
649c2c66affSColin Finck  *	ClearCommError	(KERNEL32.@)
650c2c66affSColin Finck  *
651c2c66affSColin Finck  *  Enables further I/O operations on a communications resource after
652c2c66affSColin Finck  *  supplying error and current status information.
653c2c66affSColin Finck  *
654c2c66affSColin Finck  * PARAMS
655c2c66affSColin Finck  *
656c2c66affSColin Finck  *      handle  [in]    The communication resource with the error
657c2c66affSColin Finck  *      errors  [out]   Flags indicating error the resource experienced
658c2c66affSColin Finck  *      lpStat  [out] The status of the communication resource
659c2c66affSColin Finck  * RETURNS
660c2c66affSColin Finck  *
661c2c66affSColin Finck  *  True on success, false if the communication resource handle is bad.
662c2c66affSColin Finck  */
ClearCommError(HANDLE handle,LPDWORD errors,LPCOMSTAT lpStat)663c2c66affSColin Finck BOOL WINAPI ClearCommError(HANDLE handle, LPDWORD errors, LPCOMSTAT lpStat)
664c2c66affSColin Finck {
665c2c66affSColin Finck     SERIAL_STATUS       ss;
666c2c66affSColin Finck     DWORD dwBytesReturned;
667c2c66affSColin Finck 
668c2c66affSColin Finck     if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_COMMSTATUS, NULL, 0,
669c2c66affSColin Finck                          &ss, sizeof(ss), &dwBytesReturned, NULL))
670c2c66affSColin Finck         return FALSE;
671c2c66affSColin Finck 
672c2c66affSColin Finck     if (errors)
673c2c66affSColin Finck     {
674c2c66affSColin Finck         *errors = 0;
675c2c66affSColin Finck         if (ss.Errors & SERIAL_ERROR_BREAK)             *errors |= CE_BREAK;
676c2c66affSColin Finck         if (ss.Errors & SERIAL_ERROR_FRAMING)           *errors |= CE_FRAME;
677c2c66affSColin Finck         if (ss.Errors & SERIAL_ERROR_OVERRUN)           *errors |= CE_OVERRUN;
678c2c66affSColin Finck         if (ss.Errors & SERIAL_ERROR_QUEUEOVERRUN)      *errors |= CE_RXOVER;
679c2c66affSColin Finck         if (ss.Errors & SERIAL_ERROR_PARITY)            *errors |= CE_RXPARITY;
680c2c66affSColin Finck     }
681c2c66affSColin Finck 
682c2c66affSColin Finck     if (lpStat)
683c2c66affSColin Finck     {
684c2c66affSColin Finck         memset(lpStat, 0, sizeof(*lpStat));
685c2c66affSColin Finck 
686c2c66affSColin Finck         if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_CTS)         lpStat->fCtsHold = TRUE;
687c2c66affSColin Finck         if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_DSR)         lpStat->fDsrHold = TRUE;
688c2c66affSColin Finck         if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_DCD)         lpStat->fRlsdHold = TRUE;
689c2c66affSColin Finck         if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_XON)         lpStat->fXoffHold = TRUE;
690c2c66affSColin Finck         if (ss.HoldReasons & SERIAL_TX_WAITING_XOFF_SENT)       lpStat->fXoffSent = TRUE;
691c2c66affSColin Finck         if (ss.EofReceived)                                     lpStat->fEof = TRUE;
692c2c66affSColin Finck         if (ss.WaitForImmediate)                                lpStat->fTxim = TRUE;
693c2c66affSColin Finck         lpStat->cbInQue = ss.AmountInInQueue;
694c2c66affSColin Finck         lpStat->cbOutQue = ss.AmountInOutQueue;
695c2c66affSColin Finck     }
696c2c66affSColin Finck     return TRUE;
697c2c66affSColin Finck }
698c2c66affSColin Finck 
699c2c66affSColin Finck /*****************************************************************************
700c2c66affSColin Finck  *      SetupComm       (KERNEL32.@)
701c2c66affSColin Finck  *
702c2c66affSColin Finck  *  Called after CreateFile to hint to the communication resource to use
703c2c66affSColin Finck  *  specified sizes for input and output buffers rather than the default values.
704c2c66affSColin Finck  *
705c2c66affSColin Finck  * PARAMS
706c2c66affSColin Finck  *      handle  [in]    The just created communication resource handle
707c2c66affSColin Finck  *      insize  [in]    The suggested size of the communication resources input buffer in bytes
708c2c66affSColin Finck  *      outsize [in]    The suggested size of the communication resources output buffer in bytes
709c2c66affSColin Finck  *
710c2c66affSColin Finck  * RETURNS
711c2c66affSColin Finck  *
712c2c66affSColin Finck  *  True if successful, false if the communications resource handle is bad.
713c2c66affSColin Finck  *
714c2c66affSColin Finck  * BUGS
715c2c66affSColin Finck  *
716c2c66affSColin Finck  *  Stub.
717c2c66affSColin Finck  */
SetupComm(HANDLE handle,DWORD insize,DWORD outsize)718c2c66affSColin Finck BOOL WINAPI SetupComm(HANDLE handle, DWORD insize, DWORD outsize)
719c2c66affSColin Finck {
720c2c66affSColin Finck     SERIAL_QUEUE_SIZE   sqs;
721c2c66affSColin Finck     DWORD dwBytesReturned;
722c2c66affSColin Finck 
723c2c66affSColin Finck     sqs.InSize = insize;
724c2c66affSColin Finck     sqs.OutSize = outsize;
725c2c66affSColin Finck     return DeviceIoControl(handle, IOCTL_SERIAL_SET_QUEUE_SIZE,
726c2c66affSColin Finck                            &sqs, sizeof(sqs), NULL, 0, &dwBytesReturned, NULL);
727c2c66affSColin Finck }
728c2c66affSColin Finck 
729c2c66affSColin Finck /*****************************************************************************
730c2c66affSColin Finck  *	GetCommMask	(KERNEL32.@)
731c2c66affSColin Finck  *
732c2c66affSColin Finck  *  Obtain the events associated with a communication device that will cause
733c2c66affSColin Finck  *  a call WaitCommEvent to return.
734c2c66affSColin Finck  *
735c2c66affSColin Finck  *  PARAMS
736c2c66affSColin Finck  *
737c2c66affSColin Finck  *      handle  [in]    The communications device
738c2c66affSColin Finck  *      evtmask [out]   The events which cause WaitCommEvent to return
739c2c66affSColin Finck  *
740c2c66affSColin Finck  *  RETURNS
741c2c66affSColin Finck  *
742c2c66affSColin Finck  *   True on success, fail on bad device handle etc.
743c2c66affSColin Finck  */
GetCommMask(HANDLE handle,LPDWORD evtmask)744c2c66affSColin Finck BOOL WINAPI GetCommMask(HANDLE handle, LPDWORD evtmask)
745c2c66affSColin Finck {
746c2c66affSColin Finck     DWORD dwBytesReturned;
747c2c66affSColin Finck     TRACE("handle %p, mask %p\n", handle, evtmask);
748c2c66affSColin Finck     return DeviceIoControl(handle, IOCTL_SERIAL_GET_WAIT_MASK,
749c2c66affSColin Finck                            NULL, 0, evtmask, sizeof(*evtmask), &dwBytesReturned, NULL);
750c2c66affSColin Finck }
751c2c66affSColin Finck 
752c2c66affSColin Finck /*****************************************************************************
753c2c66affSColin Finck  *	SetCommMask	(KERNEL32.@)
754c2c66affSColin Finck  *
755c2c66affSColin Finck  *  There be some things we need to hear about yon there communications device.
756c2c66affSColin Finck  *  (Set which events associated with a communication device should cause
757c2c66affSColin Finck  *  a call WaitCommEvent to return.)
758c2c66affSColin Finck  *
759c2c66affSColin Finck  * PARAMS
760c2c66affSColin Finck  *
761c2c66affSColin Finck  *      handle  [in]    The communications device
762c2c66affSColin Finck  *      evtmask [in]    The events that are to be monitored
763c2c66affSColin Finck  *
764c2c66affSColin Finck  * RETURNS
765c2c66affSColin Finck  *
766c2c66affSColin Finck  *  True on success, false on bad handle etc.
767c2c66affSColin Finck  */
SetCommMask(HANDLE handle,DWORD evtmask)768c2c66affSColin Finck BOOL WINAPI SetCommMask(HANDLE handle, DWORD evtmask)
769c2c66affSColin Finck {
770c2c66affSColin Finck     DWORD dwBytesReturned;
771c2c66affSColin Finck     TRACE("handle %p, mask %x\n", handle, evtmask);
772c2c66affSColin Finck     return DeviceIoControl(handle, IOCTL_SERIAL_SET_WAIT_MASK,
773c2c66affSColin Finck                            &evtmask, sizeof(evtmask), NULL, 0, &dwBytesReturned, NULL);
774c2c66affSColin Finck }
775c2c66affSColin Finck 
dump_dcb(const DCB * lpdcb)776c2c66affSColin Finck static void dump_dcb(const DCB* lpdcb)
777c2c66affSColin Finck {
778c2c66affSColin Finck     TRACE("bytesize=%d baudrate=%d fParity=%d Parity=%d stopbits=%d\n",
779c2c66affSColin Finck           lpdcb->ByteSize, lpdcb->BaudRate, lpdcb->fParity, lpdcb->Parity,
780c2c66affSColin Finck           (lpdcb->StopBits == ONESTOPBIT) ? 1 :
781c2c66affSColin Finck           (lpdcb->StopBits == TWOSTOPBITS) ? 2 : 0);
782c2c66affSColin Finck     TRACE("%sIXON %sIXOFF\n", (lpdcb->fOutX) ? "" : "~", (lpdcb->fInX) ? "" : "~");
783c2c66affSColin Finck     TRACE("fOutxCtsFlow=%d fRtsControl=%d\n", lpdcb->fOutxCtsFlow, lpdcb->fRtsControl);
784c2c66affSColin Finck     TRACE("fOutxDsrFlow=%d fDtrControl=%d\n", lpdcb->fOutxDsrFlow, lpdcb->fDtrControl);
785c2c66affSColin Finck     if (lpdcb->fOutxCtsFlow || lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE)
786c2c66affSColin Finck         TRACE("CRTSCTS\n");
787c2c66affSColin Finck     else
788c2c66affSColin Finck         TRACE("~CRTSCTS\n");
789c2c66affSColin Finck }
790c2c66affSColin Finck 
791c2c66affSColin Finck /*****************************************************************************
792c2c66affSColin Finck  *	SetCommState    (KERNEL32.@)
793c2c66affSColin Finck  *
794c2c66affSColin Finck  *  Re-initializes all hardware and control settings of a communications device,
795c2c66affSColin Finck  *  with values from a device control block without affecting the input and output
796c2c66affSColin Finck  *  queues.
797c2c66affSColin Finck  *
798c2c66affSColin Finck  * PARAMS
799c2c66affSColin Finck  *
800c2c66affSColin Finck  *      handle  [in]    The communications device
801c2c66affSColin Finck  *      lpdcb   [out]   The device control block
802c2c66affSColin Finck  *
803c2c66affSColin Finck  * RETURNS
804c2c66affSColin Finck  *
805c2c66affSColin Finck  *  True on success, false on failure, e.g., if the XonChar is equal to the XoffChar.
806c2c66affSColin Finck  */
SetCommState(HANDLE handle,LPDCB lpdcb)807c2c66affSColin Finck BOOL WINAPI SetCommState( HANDLE handle, LPDCB lpdcb)
808c2c66affSColin Finck {
809c2c66affSColin Finck     SERIAL_BAUD_RATE           sbr;
810c2c66affSColin Finck     SERIAL_LINE_CONTROL        slc;
811c2c66affSColin Finck     SERIAL_HANDFLOW            shf;
812c2c66affSColin Finck     SERIAL_CHARS               sc;
813c2c66affSColin Finck     DWORD dwBytesReturned;
814c2c66affSColin Finck 
815*2d4d5b63Swinesync     TRACE("handle %p, ptr %p\n", handle, lpdcb);
816*2d4d5b63Swinesync 
817c2c66affSColin Finck     if (lpdcb == NULL)
818c2c66affSColin Finck     {
819c2c66affSColin Finck         SetLastError(ERROR_INVALID_PARAMETER);
820c2c66affSColin Finck         return FALSE;
821c2c66affSColin Finck     }
822c2c66affSColin Finck     dump_dcb(lpdcb);
823c2c66affSColin Finck 
824c2c66affSColin Finck     sbr.BaudRate = lpdcb->BaudRate;
825c2c66affSColin Finck 
826c2c66affSColin Finck     slc.StopBits = lpdcb->StopBits;
827c2c66affSColin Finck     slc.Parity = lpdcb->Parity;
828c2c66affSColin Finck     slc.WordLength = lpdcb->ByteSize;
829c2c66affSColin Finck 
830c2c66affSColin Finck     shf.ControlHandShake = 0;
831c2c66affSColin Finck     shf.FlowReplace = 0;
832c2c66affSColin Finck     if (lpdcb->fOutxCtsFlow)      shf.ControlHandShake |= SERIAL_CTS_HANDSHAKE;
833c2c66affSColin Finck     if (lpdcb->fOutxDsrFlow)      shf.ControlHandShake |= SERIAL_DSR_HANDSHAKE;
834c2c66affSColin Finck     switch (lpdcb->fDtrControl)
835c2c66affSColin Finck     {
836c2c66affSColin Finck     case DTR_CONTROL_DISABLE:                                                  break;
837c2c66affSColin Finck     case DTR_CONTROL_ENABLE:      shf.ControlHandShake |= SERIAL_DTR_CONTROL;  break;
838c2c66affSColin Finck     case DTR_CONTROL_HANDSHAKE:   shf.ControlHandShake |= SERIAL_DTR_HANDSHAKE;break;
839c2c66affSColin Finck     default:
840c2c66affSColin Finck         SetLastError(ERROR_INVALID_PARAMETER);
841c2c66affSColin Finck         return FALSE;
842c2c66affSColin Finck     }
843c2c66affSColin Finck     switch (lpdcb->fRtsControl)
844c2c66affSColin Finck     {
845c2c66affSColin Finck     case RTS_CONTROL_DISABLE:                                                  break;
846c2c66affSColin Finck     case RTS_CONTROL_ENABLE:      shf.FlowReplace |= SERIAL_RTS_CONTROL;       break;
847c2c66affSColin Finck     case RTS_CONTROL_HANDSHAKE:   shf.FlowReplace |= SERIAL_RTS_HANDSHAKE;     break;
848c2c66affSColin Finck     case RTS_CONTROL_TOGGLE:      shf.FlowReplace |= SERIAL_RTS_CONTROL |
849c2c66affSColin Finck                                                      SERIAL_RTS_HANDSHAKE;     break;
850c2c66affSColin Finck     default:
851c2c66affSColin Finck         SetLastError(ERROR_INVALID_PARAMETER);
852c2c66affSColin Finck         return FALSE;
853c2c66affSColin Finck     }
854c2c66affSColin Finck     if (lpdcb->fDsrSensitivity)   shf.ControlHandShake |= SERIAL_DSR_SENSITIVITY;
855c2c66affSColin Finck     if (lpdcb->fAbortOnError)     shf.ControlHandShake |= SERIAL_ERROR_ABORT;
856c2c66affSColin Finck 
857c2c66affSColin Finck     if (lpdcb->fErrorChar)        shf.FlowReplace |= SERIAL_ERROR_CHAR;
858c2c66affSColin Finck     if (lpdcb->fNull)             shf.FlowReplace |= SERIAL_NULL_STRIPPING;
859c2c66affSColin Finck     if (lpdcb->fTXContinueOnXoff) shf.FlowReplace |= SERIAL_XOFF_CONTINUE;
860c2c66affSColin Finck     if (lpdcb->fOutX)             shf.FlowReplace |= SERIAL_AUTO_TRANSMIT;
861c2c66affSColin Finck     if (lpdcb->fInX)              shf.FlowReplace |= SERIAL_AUTO_RECEIVE;
862c2c66affSColin Finck 
863c2c66affSColin Finck     shf.XonLimit = lpdcb->XonLim;
864c2c66affSColin Finck     shf.XoffLimit = lpdcb->XoffLim;
865c2c66affSColin Finck 
866c2c66affSColin Finck     sc.EofChar = lpdcb->EofChar;
867c2c66affSColin Finck     sc.ErrorChar = lpdcb->ErrorChar;
868c2c66affSColin Finck     sc.BreakChar = 0;
869c2c66affSColin Finck     sc.EventChar = lpdcb->EvtChar;
870c2c66affSColin Finck     sc.XonChar = lpdcb->XonChar;
871c2c66affSColin Finck     sc.XoffChar = lpdcb->XoffChar;
872c2c66affSColin Finck 
873c2c66affSColin Finck     /* note: change DTR/RTS lines after setting the comm attributes,
874c2c66affSColin Finck      * so flow control does not interfere.
875c2c66affSColin Finck      */
876c2c66affSColin Finck     return (DeviceIoControl(handle, IOCTL_SERIAL_SET_BAUD_RATE,
877c2c66affSColin Finck                             &sbr, sizeof(sbr), NULL, 0, &dwBytesReturned, NULL) &&
878c2c66affSColin Finck             DeviceIoControl(handle, IOCTL_SERIAL_SET_LINE_CONTROL,
879c2c66affSColin Finck                             &slc, sizeof(slc), NULL, 0, &dwBytesReturned, NULL) &&
880c2c66affSColin Finck             DeviceIoControl(handle, IOCTL_SERIAL_SET_HANDFLOW,
881c2c66affSColin Finck                             &shf, sizeof(shf), NULL, 0, &dwBytesReturned, NULL) &&
882c2c66affSColin Finck             DeviceIoControl(handle, IOCTL_SERIAL_SET_CHARS,
883c2c66affSColin Finck                             &sc, sizeof(sc), NULL, 0, &dwBytesReturned, NULL));
884c2c66affSColin Finck }
885c2c66affSColin Finck 
886c2c66affSColin Finck 
887c2c66affSColin Finck /*****************************************************************************
888c2c66affSColin Finck  *	GetCommState	(KERNEL32.@)
889c2c66affSColin Finck  *
890c2c66affSColin Finck  *  Fills in a device control block with information from a communications device.
891c2c66affSColin Finck  *
892c2c66affSColin Finck  * PARAMS
893c2c66affSColin Finck  *      handle          [in]    The communications device
894c2c66affSColin Finck  *      lpdcb           [out]   The device control block
895c2c66affSColin Finck  *
896c2c66affSColin Finck  * RETURNS
897c2c66affSColin Finck  *
898c2c66affSColin Finck  *  True on success, false if the communication device handle is bad etc
899c2c66affSColin Finck  *
900c2c66affSColin Finck  * BUGS
901c2c66affSColin Finck  *
902c2c66affSColin Finck  *  XonChar and XoffChar are not set.
903c2c66affSColin Finck  */
GetCommState(HANDLE handle,LPDCB lpdcb)904c2c66affSColin Finck BOOL WINAPI GetCommState(HANDLE handle, LPDCB lpdcb)
905c2c66affSColin Finck {
906c2c66affSColin Finck     SERIAL_BAUD_RATE    sbr;
907c2c66affSColin Finck     SERIAL_LINE_CONTROL slc;
908c2c66affSColin Finck     SERIAL_HANDFLOW     shf;
909c2c66affSColin Finck     SERIAL_CHARS        sc;
910c2c66affSColin Finck     DWORD dwBytesReturned;
911c2c66affSColin Finck 
912c2c66affSColin Finck     TRACE("handle %p, ptr %p\n", handle, lpdcb);
913c2c66affSColin Finck 
914c2c66affSColin Finck     if (!lpdcb)
915c2c66affSColin Finck     {
916c2c66affSColin Finck         SetLastError(ERROR_INVALID_PARAMETER);
917c2c66affSColin Finck         return FALSE;
918c2c66affSColin Finck     }
919c2c66affSColin Finck 
920c2c66affSColin Finck     if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_BAUD_RATE,
921c2c66affSColin Finck                          NULL, 0, &sbr, sizeof(sbr), &dwBytesReturned, NULL) ||
922c2c66affSColin Finck         !DeviceIoControl(handle, IOCTL_SERIAL_GET_LINE_CONTROL,
923c2c66affSColin Finck                          NULL, 0, &slc, sizeof(slc), &dwBytesReturned, NULL) ||
924c2c66affSColin Finck         !DeviceIoControl(handle, IOCTL_SERIAL_GET_HANDFLOW,
925c2c66affSColin Finck                          NULL, 0, &shf, sizeof(shf), &dwBytesReturned, NULL) ||
926c2c66affSColin Finck         !DeviceIoControl(handle, IOCTL_SERIAL_GET_CHARS,
927c2c66affSColin Finck                          NULL, 0, &sc, sizeof(sc), &dwBytesReturned, NULL))
928c2c66affSColin Finck         return FALSE;
929c2c66affSColin Finck 
930c2c66affSColin Finck     memset(lpdcb, 0, sizeof(*lpdcb));
931c2c66affSColin Finck     lpdcb->DCBlength = sizeof(*lpdcb);
932c2c66affSColin Finck 
933c2c66affSColin Finck     /* yes, they seem no never be (re)set on NT */
934c2c66affSColin Finck     lpdcb->fBinary = 1;
935c2c66affSColin Finck     lpdcb->fParity = 0;
936c2c66affSColin Finck 
937c2c66affSColin Finck     lpdcb->BaudRate = sbr.BaudRate;
938c2c66affSColin Finck 
939c2c66affSColin Finck     lpdcb->StopBits = slc.StopBits;
940c2c66affSColin Finck     lpdcb->Parity = slc.Parity;
941c2c66affSColin Finck     lpdcb->ByteSize = slc.WordLength;
942c2c66affSColin Finck 
943c2c66affSColin Finck     if (shf.ControlHandShake & SERIAL_CTS_HANDSHAKE)    lpdcb->fOutxCtsFlow = 1;
944c2c66affSColin Finck     if (shf.ControlHandShake & SERIAL_DSR_HANDSHAKE)    lpdcb->fOutxDsrFlow = 1;
945c2c66affSColin Finck     switch (shf.ControlHandShake & (SERIAL_DTR_CONTROL | SERIAL_DTR_HANDSHAKE))
946c2c66affSColin Finck     {
947c2c66affSColin Finck     case 0:                     lpdcb->fDtrControl = DTR_CONTROL_DISABLE; break;
948c2c66affSColin Finck     case SERIAL_DTR_CONTROL:    lpdcb->fDtrControl = DTR_CONTROL_ENABLE; break;
949c2c66affSColin Finck     case SERIAL_DTR_HANDSHAKE:  lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE; break;
950c2c66affSColin Finck     }
951c2c66affSColin Finck     switch (shf.FlowReplace & (SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE))
952c2c66affSColin Finck     {
953c2c66affSColin Finck     case 0:                     lpdcb->fRtsControl = RTS_CONTROL_DISABLE; break;
954c2c66affSColin Finck     case SERIAL_RTS_CONTROL:    lpdcb->fRtsControl = RTS_CONTROL_ENABLE; break;
955c2c66affSColin Finck     case SERIAL_RTS_HANDSHAKE:  lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE; break;
956c2c66affSColin Finck     case SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE:
957c2c66affSColin Finck                                 lpdcb->fRtsControl = RTS_CONTROL_TOGGLE; break;
958c2c66affSColin Finck     }
959c2c66affSColin Finck     if (shf.ControlHandShake & SERIAL_DSR_SENSITIVITY)  lpdcb->fDsrSensitivity = 1;
960c2c66affSColin Finck     if (shf.ControlHandShake & SERIAL_ERROR_ABORT)      lpdcb->fAbortOnError = 1;
961c2c66affSColin Finck     if (shf.FlowReplace & SERIAL_ERROR_CHAR)            lpdcb->fErrorChar = 1;
962c2c66affSColin Finck     if (shf.FlowReplace & SERIAL_NULL_STRIPPING)        lpdcb->fNull = 1;
963c2c66affSColin Finck     if (shf.FlowReplace & SERIAL_XOFF_CONTINUE)         lpdcb->fTXContinueOnXoff = 1;
964c2c66affSColin Finck     lpdcb->XonLim = shf.XonLimit;
965c2c66affSColin Finck     lpdcb->XoffLim = shf.XoffLimit;
966c2c66affSColin Finck 
967c2c66affSColin Finck     if (shf.FlowReplace & SERIAL_AUTO_TRANSMIT) lpdcb->fOutX = 1;
968c2c66affSColin Finck     if (shf.FlowReplace & SERIAL_AUTO_RECEIVE)  lpdcb->fInX = 1;
969c2c66affSColin Finck 
970c2c66affSColin Finck     lpdcb->EofChar = sc.EofChar;
971c2c66affSColin Finck     lpdcb->ErrorChar = sc.ErrorChar;
972c2c66affSColin Finck     lpdcb->EvtChar = sc.EventChar;
973c2c66affSColin Finck     lpdcb->XonChar = sc.XonChar;
974c2c66affSColin Finck     lpdcb->XoffChar = sc.XoffChar;
975c2c66affSColin Finck 
976c2c66affSColin Finck     TRACE("OK\n");
977c2c66affSColin Finck     dump_dcb(lpdcb);
978c2c66affSColin Finck 
979c2c66affSColin Finck     return TRUE;
980c2c66affSColin Finck }
981c2c66affSColin Finck 
982c2c66affSColin Finck /*****************************************************************************
983c2c66affSColin Finck  *	TransmitCommChar	(KERNEL32.@)
984c2c66affSColin Finck  *
985c2c66affSColin Finck  *  Transmits a single character in front of any pending characters in the
986c2c66affSColin Finck  *  output buffer.  Usually used to send an interrupt character to a host.
987c2c66affSColin Finck  *
988c2c66affSColin Finck  * PARAMS
989c2c66affSColin Finck  *      hComm           [in]    The communication device in need of a command character
990c2c66affSColin Finck  *      chTransmit      [in]    The character to transmit
991c2c66affSColin Finck  *
992c2c66affSColin Finck  * RETURNS
993c2c66affSColin Finck  *
994c2c66affSColin Finck  *  True if the call succeeded, false if the previous command character to the
995c2c66affSColin Finck  *  same device has not been sent yet the handle is bad etc.
996c2c66affSColin Finck  *
997c2c66affSColin Finck  */
TransmitCommChar(HANDLE hComm,CHAR chTransmit)998c2c66affSColin Finck BOOL WINAPI TransmitCommChar(HANDLE hComm, CHAR chTransmit)
999c2c66affSColin Finck {
1000c2c66affSColin Finck     DWORD dwBytesReturned;
1001c2c66affSColin Finck     return DeviceIoControl(hComm, IOCTL_SERIAL_IMMEDIATE_CHAR,
1002c2c66affSColin Finck                            &chTransmit, sizeof(chTransmit), NULL, 0, &dwBytesReturned, NULL);
1003c2c66affSColin Finck }
1004c2c66affSColin Finck 
1005c2c66affSColin Finck 
1006c2c66affSColin Finck /*****************************************************************************
1007c2c66affSColin Finck  *	GetCommTimeouts		(KERNEL32.@)
1008c2c66affSColin Finck  *
1009c2c66affSColin Finck  *  Obtains the request timeout values for the communications device.
1010c2c66affSColin Finck  *
1011c2c66affSColin Finck  * PARAMS
1012c2c66affSColin Finck  *      hComm           [in]    The communications device
1013c2c66affSColin Finck  *      lptimeouts      [out]   The struct of request timeouts
1014c2c66affSColin Finck  *
1015c2c66affSColin Finck  * RETURNS
1016c2c66affSColin Finck  *
1017c2c66affSColin Finck  *  True on success, false if communications device handle is bad
1018c2c66affSColin Finck  *  or the target structure is null.
1019c2c66affSColin Finck  */
GetCommTimeouts(HANDLE hComm,LPCOMMTIMEOUTS lptimeouts)1020c2c66affSColin Finck BOOL WINAPI GetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts)
1021c2c66affSColin Finck {
1022c2c66affSColin Finck     SERIAL_TIMEOUTS     st;
1023c2c66affSColin Finck     DWORD dwBytesReturned;
1024c2c66affSColin Finck 
1025c2c66affSColin Finck     TRACE("(%p, %p)\n", hComm, lptimeouts);
1026c2c66affSColin Finck     if (!lptimeouts)
1027c2c66affSColin Finck     {
1028c2c66affSColin Finck         SetLastError(ERROR_INVALID_PARAMETER);
1029c2c66affSColin Finck         return FALSE;
1030c2c66affSColin Finck     }
1031c2c66affSColin Finck     if (!DeviceIoControl(hComm, IOCTL_SERIAL_GET_TIMEOUTS,
1032c2c66affSColin Finck                          NULL, 0, &st, sizeof(st), &dwBytesReturned, NULL))
1033c2c66affSColin Finck         return FALSE;
1034c2c66affSColin Finck     lptimeouts->ReadIntervalTimeout         = st.ReadIntervalTimeout;
1035c2c66affSColin Finck     lptimeouts->ReadTotalTimeoutMultiplier  = st.ReadTotalTimeoutMultiplier;
1036c2c66affSColin Finck     lptimeouts->ReadTotalTimeoutConstant    = st.ReadTotalTimeoutConstant;
1037c2c66affSColin Finck     lptimeouts->WriteTotalTimeoutMultiplier = st.WriteTotalTimeoutMultiplier;
1038c2c66affSColin Finck     lptimeouts->WriteTotalTimeoutConstant   = st.WriteTotalTimeoutConstant;
1039c2c66affSColin Finck     return TRUE;
1040c2c66affSColin Finck }
1041c2c66affSColin Finck 
1042c2c66affSColin Finck /*****************************************************************************
1043c2c66affSColin Finck  *	SetCommTimeouts		(KERNEL32.@)
1044c2c66affSColin Finck  *
1045c2c66affSColin Finck  * Sets the timeouts used when reading and writing data to/from COMM ports.
1046c2c66affSColin Finck  *
1047c2c66affSColin Finck  * PARAMS
1048c2c66affSColin Finck  *      hComm           [in]    handle of COMM device
1049c2c66affSColin Finck  *      lptimeouts      [in]    pointer to COMMTIMEOUTS structure
1050c2c66affSColin Finck  *
1051c2c66affSColin Finck  * ReadIntervalTimeout
1052c2c66affSColin Finck  *     - converted and passes to linux kernel as c_cc[VTIME]
1053c2c66affSColin Finck  * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant
1054c2c66affSColin Finck  *     - used in ReadFile to calculate GetOverlappedResult's timeout
1055c2c66affSColin Finck  * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant
1056c2c66affSColin Finck  *     - used in WriteFile to calculate GetOverlappedResult's timeout
1057c2c66affSColin Finck  *
1058c2c66affSColin Finck  * RETURNS
1059c2c66affSColin Finck  *
1060c2c66affSColin Finck  *  True if the timeouts were set, false otherwise.
1061c2c66affSColin Finck  */
SetCommTimeouts(HANDLE hComm,LPCOMMTIMEOUTS lptimeouts)1062c2c66affSColin Finck BOOL WINAPI SetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts)
1063c2c66affSColin Finck {
1064c2c66affSColin Finck     SERIAL_TIMEOUTS     st;
1065c2c66affSColin Finck     DWORD dwBytesReturned;
1066c2c66affSColin Finck 
1067c2c66affSColin Finck     TRACE("(%p, %p)\n", hComm, lptimeouts);
1068c2c66affSColin Finck 
1069c2c66affSColin Finck     if (lptimeouts == NULL)
1070c2c66affSColin Finck     {
1071c2c66affSColin Finck         SetLastError(ERROR_INVALID_PARAMETER);
1072c2c66affSColin Finck         return FALSE;
1073c2c66affSColin Finck     }
1074c2c66affSColin Finck     st.ReadIntervalTimeout         = lptimeouts->ReadIntervalTimeout;
1075c2c66affSColin Finck     st.ReadTotalTimeoutMultiplier  = lptimeouts->ReadTotalTimeoutMultiplier;
1076c2c66affSColin Finck     st.ReadTotalTimeoutConstant    = lptimeouts->ReadTotalTimeoutConstant;
1077c2c66affSColin Finck     st.WriteTotalTimeoutMultiplier = lptimeouts->WriteTotalTimeoutMultiplier;
1078c2c66affSColin Finck     st.WriteTotalTimeoutConstant   = lptimeouts->WriteTotalTimeoutConstant;
1079c2c66affSColin Finck 
1080c2c66affSColin Finck     return DeviceIoControl(hComm, IOCTL_SERIAL_SET_TIMEOUTS,
1081c2c66affSColin Finck                            &st, sizeof(st), NULL, 0, &dwBytesReturned, NULL);
1082c2c66affSColin Finck }
1083c2c66affSColin Finck 
1084c2c66affSColin Finck /***********************************************************************
1085c2c66affSColin Finck  *           GetCommModemStatus   (KERNEL32.@)
1086c2c66affSColin Finck  *
1087c2c66affSColin Finck  *  Obtains the four control register bits if supported by the hardware.
1088c2c66affSColin Finck  *
1089c2c66affSColin Finck  * PARAMS
1090c2c66affSColin Finck  *
1091c2c66affSColin Finck  *      hFile           [in]    The communications device
1092c2c66affSColin Finck  *      lpModemStat     [out]   The control register bits
1093c2c66affSColin Finck  *
1094c2c66affSColin Finck  * RETURNS
1095c2c66affSColin Finck  *
1096c2c66affSColin Finck  *  True if the communications handle was good and for hardware that
1097c2c66affSColin Finck  *  control register access, false otherwise.
1098c2c66affSColin Finck  */
GetCommModemStatus(HANDLE hFile,LPDWORD lpModemStat)1099c2c66affSColin Finck BOOL WINAPI GetCommModemStatus(HANDLE hFile, LPDWORD lpModemStat)
1100c2c66affSColin Finck {
1101c2c66affSColin Finck     DWORD dwBytesReturned;
1102c2c66affSColin Finck     return DeviceIoControl(hFile, IOCTL_SERIAL_GET_MODEMSTATUS,
1103c2c66affSColin Finck                            NULL, 0, lpModemStat, sizeof(DWORD), &dwBytesReturned, NULL);
1104c2c66affSColin Finck }
1105c2c66affSColin Finck 
1106c2c66affSColin Finck /***********************************************************************
1107c2c66affSColin Finck  *           WaitCommEvent   (KERNEL32.@)
1108c2c66affSColin Finck  *
1109c2c66affSColin Finck  * Wait until something interesting happens on a COMM port.
1110c2c66affSColin Finck  * Interesting things (events) are set by calling SetCommMask before
1111c2c66affSColin Finck  * this function is called.
1112c2c66affSColin Finck  *
1113c2c66affSColin Finck  * RETURNS
1114c2c66affSColin Finck  *   TRUE if successful
1115c2c66affSColin Finck  *   FALSE if failure
1116c2c66affSColin Finck  *
1117c2c66affSColin Finck  *   The set of detected events will be written to *lpdwEventMask
1118c2c66affSColin Finck  *   ERROR_IO_PENDING will be returned the overlapped structure was passed
1119c2c66affSColin Finck  *
1120c2c66affSColin Finck  * BUGS:
1121c2c66affSColin Finck  *  Only supports EV_RXCHAR and EV_TXEMPTY
1122c2c66affSColin Finck  */
WaitCommEvent(HANDLE hFile,LPDWORD lpdwEvents,LPOVERLAPPED lpOverlapped)1123c2c66affSColin Finck BOOL WINAPI WaitCommEvent(
1124c2c66affSColin Finck     HANDLE hFile,              /* [in] handle of comm port to wait for */
1125c2c66affSColin Finck     LPDWORD lpdwEvents,        /* [out] event(s) that were detected */
1126c2c66affSColin Finck     LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */
1127c2c66affSColin Finck {
1128c2c66affSColin Finck     return DeviceIoControl(hFile, IOCTL_SERIAL_WAIT_ON_MASK, NULL, 0,
1129c2c66affSColin Finck                            lpdwEvents, sizeof(DWORD), NULL, lpOverlapped);
1130c2c66affSColin Finck }
1131c2c66affSColin Finck 
1132c2c66affSColin Finck /***********************************************************************
1133c2c66affSColin Finck  *           GetCommProperties   (KERNEL32.@)
1134c2c66affSColin Finck  *
1135c2c66affSColin Finck  * This function fills in a structure with the capabilities of the
1136c2c66affSColin Finck  * communications port driver.
1137c2c66affSColin Finck  *
1138c2c66affSColin Finck  * RETURNS
1139c2c66affSColin Finck  *
1140c2c66affSColin Finck  *  TRUE on success, FALSE on failure
1141c2c66affSColin Finck  *  If successful, the lpCommProp structure be filled in with
1142c2c66affSColin Finck  *  properties of the comm port.
1143c2c66affSColin Finck  */
GetCommProperties(HANDLE hFile,LPCOMMPROP lpCommProp)1144c2c66affSColin Finck BOOL WINAPI GetCommProperties(
1145c2c66affSColin Finck     HANDLE hFile,          /* [in] handle of the comm port */
1146c2c66affSColin Finck     LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */
1147c2c66affSColin Finck {
1148c2c66affSColin Finck     TRACE("(%p %p)\n",hFile,lpCommProp);
1149c2c66affSColin Finck     if(!lpCommProp)
1150c2c66affSColin Finck         return FALSE;
1151c2c66affSColin Finck 
1152c2c66affSColin Finck     /*
1153c2c66affSColin Finck      * These values should be valid for LINUX's serial driver
1154c2c66affSColin Finck      * FIXME: Perhaps they deserve an #ifdef LINUX
1155c2c66affSColin Finck      */
1156c2c66affSColin Finck     memset(lpCommProp,0,sizeof(COMMPROP));
1157c2c66affSColin Finck     lpCommProp->wPacketLength       = 1;
1158c2c66affSColin Finck     lpCommProp->wPacketVersion      = 1;
1159c2c66affSColin Finck     lpCommProp->dwServiceMask       = SP_SERIALCOMM;
1160c2c66affSColin Finck     lpCommProp->dwMaxTxQueue        = 4096;
1161c2c66affSColin Finck     lpCommProp->dwMaxRxQueue        = 4096;
1162c2c66affSColin Finck     lpCommProp->dwMaxBaud           = BAUD_115200;
1163c2c66affSColin Finck     lpCommProp->dwProvSubType       = PST_RS232;
1164c2c66affSColin Finck     lpCommProp->dwProvCapabilities  = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS | PCF_TOTALTIMEOUTS;
1165c2c66affSColin Finck     lpCommProp->dwSettableParams    = SP_BAUD | SP_DATABITS | SP_HANDSHAKING |
1166c2c66affSColin Finck                                       SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ;
1167c2c66affSColin Finck     lpCommProp->dwSettableBaud      = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 |
1168c2c66affSColin Finck                 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 |
1169c2c66affSColin Finck                 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ;
1170c2c66affSColin Finck     lpCommProp->wSettableData       = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ;
1171c2c66affSColin Finck     lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 |
1172c2c66affSColin Finck                 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE;
1173c2c66affSColin Finck     lpCommProp->dwCurrentTxQueue    = lpCommProp->dwMaxTxQueue;
1174c2c66affSColin Finck     lpCommProp->dwCurrentRxQueue    = lpCommProp->dwMaxRxQueue;
1175c2c66affSColin Finck 
1176c2c66affSColin Finck     return TRUE;
1177c2c66affSColin Finck }
1178c2c66affSColin Finck 
1179c2c66affSColin Finck /***********************************************************************
1180c2c66affSColin Finck  * FIXME:
1181c2c66affSColin Finck  * The functionality of CommConfigDialogA, GetDefaultCommConfig and
1182c2c66affSColin Finck  * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
1183c2c66affSColin Finck  * This is dependent on the type of COMM port, but since it is doubtful
1184c2c66affSColin Finck  * anybody will get around to implementing support for fancy serial
1185c2c66affSColin Finck  * ports in WINE, this is hardcoded for the time being.  The name of
1186c2c66affSColin Finck  * this DLL should be stored in and read from the system registry in
1187c2c66affSColin Finck  * the hive HKEY_LOCAL_MACHINE, key
1188c2c66affSColin Finck  * System\\CurrentControlSet\\Services\\Class\\Ports\\????
1189c2c66affSColin Finck  * where ???? is the port number... that is determined by PNP
1190c2c66affSColin Finck  * The DLL should be loaded when the COMM port is opened, and closed
1191c2c66affSColin Finck  * when the COMM port is closed. - MJM 20 June 2000
1192c2c66affSColin Finck  ***********************************************************************/
1193c2c66affSColin Finck static const WCHAR lpszSerialUI[] = {
1194c2c66affSColin Finck    's','e','r','i','a','l','u','i','.','d','l','l',0 };
1195c2c66affSColin Finck 
1196c2c66affSColin Finck 
1197c2c66affSColin Finck /***********************************************************************
1198c2c66affSColin Finck  *           CommConfigDialogA   (KERNEL32.@)
1199c2c66affSColin Finck  *
1200c2c66affSColin Finck  * Raises a dialog that allows the user to configure a comm port.
1201c2c66affSColin Finck  * Fills the COMMCONFIG struct with information specified by the user.
1202c2c66affSColin Finck  * This function should call a similar routine in the COMM driver...
1203c2c66affSColin Finck  *
1204c2c66affSColin Finck  * RETURNS
1205c2c66affSColin Finck  *
1206c2c66affSColin Finck  *  TRUE on success, FALSE on failure
1207c2c66affSColin Finck  *  If successful, the lpCommConfig structure will contain a new
1208c2c66affSColin Finck  *  configuration for the comm port, as specified by the user.
1209c2c66affSColin Finck  *
1210c2c66affSColin Finck  * BUGS
1211c2c66affSColin Finck  *  The library with the CommConfigDialog code is never unloaded.
1212c2c66affSColin Finck  * Perhaps this should be done when the comm port is closed?
1213c2c66affSColin Finck  */
CommConfigDialogA(LPCSTR lpszDevice,HWND hWnd,LPCOMMCONFIG lpCommConfig)1214c2c66affSColin Finck BOOL WINAPI CommConfigDialogA(
1215c2c66affSColin Finck     LPCSTR lpszDevice,         /* [in] name of communications device */
1216c2c66affSColin Finck     HWND hWnd,                 /* [in] parent window for the dialog */
1217c2c66affSColin Finck     LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1218c2c66affSColin Finck {
1219c2c66affSColin Finck     LPWSTR  lpDeviceW = NULL;
1220c2c66affSColin Finck     DWORD   len;
1221c2c66affSColin Finck     BOOL    r;
1222c2c66affSColin Finck 
1223c2c66affSColin Finck     TRACE("(%s, %p, %p)\n", debugstr_a(lpszDevice), hWnd, lpCommConfig);
1224c2c66affSColin Finck 
1225c2c66affSColin Finck     if (lpszDevice)
1226c2c66affSColin Finck     {
1227c2c66affSColin Finck         len = MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, NULL, 0 );
1228c2c66affSColin Finck         lpDeviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1229c2c66affSColin Finck         MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, lpDeviceW, len );
1230c2c66affSColin Finck     }
1231c2c66affSColin Finck     r = CommConfigDialogW(lpDeviceW, hWnd, lpCommConfig);
1232c2c66affSColin Finck     HeapFree( GetProcessHeap(), 0, lpDeviceW );
1233c2c66affSColin Finck     return r;
1234c2c66affSColin Finck }
1235c2c66affSColin Finck 
1236c2c66affSColin Finck /***********************************************************************
1237c2c66affSColin Finck  *           CommConfigDialogW   (KERNEL32.@)
1238c2c66affSColin Finck  *
1239c2c66affSColin Finck  * See CommConfigDialogA.
1240c2c66affSColin Finck  */
CommConfigDialogW(LPCWSTR lpszDevice,HWND hWnd,LPCOMMCONFIG lpCommConfig)1241c2c66affSColin Finck BOOL WINAPI CommConfigDialogW(
1242c2c66affSColin Finck     LPCWSTR lpszDevice,        /* [in] name of communications device */
1243c2c66affSColin Finck     HWND hWnd,                 /* [in] parent window for the dialog */
1244c2c66affSColin Finck     LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
1245c2c66affSColin Finck {
1246c2c66affSColin Finck     DWORD (WINAPI *pCommConfigDialog)(LPCWSTR, HWND, LPCOMMCONFIG);
1247c2c66affSColin Finck     HMODULE hConfigModule;
1248c2c66affSColin Finck     DWORD   res = ERROR_INVALID_PARAMETER;
1249c2c66affSColin Finck 
1250c2c66affSColin Finck     TRACE("(%s, %p, %p)\n", debugstr_w(lpszDevice), hWnd, lpCommConfig);
1251c2c66affSColin Finck     hConfigModule = LoadLibraryW(lpszSerialUI);
1252c2c66affSColin Finck 
1253c2c66affSColin Finck     if (hConfigModule) {
1254c2c66affSColin Finck         pCommConfigDialog = (void *)GetProcAddress(hConfigModule, "drvCommConfigDialogW");
1255c2c66affSColin Finck         if (pCommConfigDialog) {
1256c2c66affSColin Finck             res = pCommConfigDialog(lpszDevice, hWnd, lpCommConfig);
1257c2c66affSColin Finck         }
1258c2c66affSColin Finck         FreeLibrary(hConfigModule);
1259c2c66affSColin Finck     }
1260c2c66affSColin Finck 
1261c2c66affSColin Finck     if (res) SetLastError(res);
1262c2c66affSColin Finck     return (res == ERROR_SUCCESS);
1263c2c66affSColin Finck }
1264c2c66affSColin Finck 
1265c2c66affSColin Finck /***********************************************************************
1266c2c66affSColin Finck  *           GetCommConfig     (KERNEL32.@)
1267c2c66affSColin Finck  *
1268c2c66affSColin Finck  * Fill in the COMMCONFIG structure for the comm port hFile
1269c2c66affSColin Finck  *
1270c2c66affSColin Finck  * RETURNS
1271c2c66affSColin Finck  *
1272c2c66affSColin Finck  *  TRUE on success, FALSE on failure
1273c2c66affSColin Finck  *  If successful, lpCommConfig contains the comm port configuration.
1274c2c66affSColin Finck  *
1275c2c66affSColin Finck  * BUGS
1276c2c66affSColin Finck  *
1277c2c66affSColin Finck  */
GetCommConfig(HANDLE hFile,LPCOMMCONFIG lpCommConfig,LPDWORD lpdwSize)1278c2c66affSColin Finck BOOL WINAPI GetCommConfig(
1279c2c66affSColin Finck     HANDLE       hFile,        /* [in] The communications device. */
1280c2c66affSColin Finck     LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */
1281c2c66affSColin Finck     LPDWORD      lpdwSize)     /* [in/out] Initially the size of the configuration buffer/structure,
1282c2c66affSColin Finck                                   afterwards the number of bytes copied to the buffer or
1283c2c66affSColin Finck                                   the needed size of the buffer. */
1284c2c66affSColin Finck {
1285c2c66affSColin Finck     BOOL r;
1286c2c66affSColin Finck 
1287c2c66affSColin Finck     TRACE("(%p, %p, %p) *lpdwSize: %u\n", hFile, lpCommConfig, lpdwSize, lpdwSize ? *lpdwSize : 0 );
1288c2c66affSColin Finck 
1289c2c66affSColin Finck     if(lpCommConfig == NULL)
1290c2c66affSColin Finck         return FALSE;
1291c2c66affSColin Finck     r = *lpdwSize < sizeof(COMMCONFIG); /* TRUE if not enough space */
1292c2c66affSColin Finck     *lpdwSize = sizeof(COMMCONFIG);
1293c2c66affSColin Finck     if(r)
1294c2c66affSColin Finck         return FALSE;
1295c2c66affSColin Finck 
1296c2c66affSColin Finck     lpCommConfig->dwSize = sizeof(COMMCONFIG);
1297c2c66affSColin Finck     lpCommConfig->wVersion = 1;
1298c2c66affSColin Finck     lpCommConfig->wReserved = 0;
1299c2c66affSColin Finck     r = GetCommState(hFile,&lpCommConfig->dcb);
1300c2c66affSColin Finck     lpCommConfig->dwProviderSubType = PST_RS232;
1301c2c66affSColin Finck     lpCommConfig->dwProviderOffset = 0;
1302c2c66affSColin Finck     lpCommConfig->dwProviderSize = 0;
1303c2c66affSColin Finck 
1304c2c66affSColin Finck     return r;
1305c2c66affSColin Finck }
1306c2c66affSColin Finck 
1307c2c66affSColin Finck /***********************************************************************
1308c2c66affSColin Finck  *           SetCommConfig     (KERNEL32.@)
1309c2c66affSColin Finck  *
1310c2c66affSColin Finck  *  Sets the configuration of the communications device.
1311c2c66affSColin Finck  *
1312c2c66affSColin Finck  * RETURNS
1313c2c66affSColin Finck  *
1314c2c66affSColin Finck  *  True on success, false if the handle was bad is not a communications device.
1315c2c66affSColin Finck  */
SetCommConfig(HANDLE hFile,LPCOMMCONFIG lpCommConfig,DWORD dwSize)1316c2c66affSColin Finck BOOL WINAPI SetCommConfig(
1317c2c66affSColin Finck     HANDLE       hFile,		/* [in] The communications device. */
1318c2c66affSColin Finck     LPCOMMCONFIG lpCommConfig,	/* [in] The desired configuration. */
1319c2c66affSColin Finck     DWORD dwSize) 		/* [in] size of the lpCommConfig struct */
1320c2c66affSColin Finck {
1321c2c66affSColin Finck     TRACE("(%p, %p, %u)\n", hFile, lpCommConfig, dwSize);
1322c2c66affSColin Finck     return SetCommState(hFile,&lpCommConfig->dcb);
1323c2c66affSColin Finck }
1324c2c66affSColin Finck 
1325c2c66affSColin Finck /***********************************************************************
1326c2c66affSColin Finck  *           SetDefaultCommConfigW  (KERNEL32.@)
1327c2c66affSColin Finck  *
1328c2c66affSColin Finck  * Initializes the default configuration for a communication device.
1329c2c66affSColin Finck  *
1330c2c66affSColin Finck  * PARAMS
1331c2c66affSColin Finck  *  lpszDevice   [I] Name of the device targeted for configuration
1332c2c66affSColin Finck  *  lpCommConfig [I] PTR to a buffer with the configuration for the device
1333c2c66affSColin Finck  *  dwSize       [I] Number of bytes in the buffer
1334c2c66affSColin Finck  *
1335c2c66affSColin Finck  * RETURNS
1336c2c66affSColin Finck  *  Failure: FALSE
1337c2c66affSColin Finck  *  Success: TRUE, and default configuration saved
1338c2c66affSColin Finck  *
1339c2c66affSColin Finck  */
SetDefaultCommConfigW(LPCWSTR lpszDevice,LPCOMMCONFIG lpCommConfig,DWORD dwSize)1340c2c66affSColin Finck BOOL WINAPI SetDefaultCommConfigW(LPCWSTR lpszDevice, LPCOMMCONFIG lpCommConfig, DWORD dwSize)
1341c2c66affSColin Finck {
1342c2c66affSColin Finck     BOOL (WINAPI *lpfnSetDefaultCommConfig)(LPCWSTR, LPCOMMCONFIG, DWORD);
1343c2c66affSColin Finck     HMODULE hConfigModule;
1344c2c66affSColin Finck     BOOL r = FALSE;
1345c2c66affSColin Finck 
1346c2c66affSColin Finck     TRACE("(%s, %p, %u)\n", debugstr_w(lpszDevice), lpCommConfig, dwSize);
1347c2c66affSColin Finck 
1348c2c66affSColin Finck     hConfigModule = LoadLibraryW(lpszSerialUI);
1349c2c66affSColin Finck     if(!hConfigModule)
1350c2c66affSColin Finck         return r;
1351c2c66affSColin Finck 
1352c2c66affSColin Finck     lpfnSetDefaultCommConfig = (void *)GetProcAddress(hConfigModule, "drvSetDefaultCommConfigW");
1353c2c66affSColin Finck     if (lpfnSetDefaultCommConfig)
1354c2c66affSColin Finck         r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
1355c2c66affSColin Finck 
1356c2c66affSColin Finck     FreeLibrary(hConfigModule);
1357c2c66affSColin Finck 
1358c2c66affSColin Finck     return r;
1359c2c66affSColin Finck }
1360c2c66affSColin Finck 
1361c2c66affSColin Finck 
1362c2c66affSColin Finck /***********************************************************************
1363c2c66affSColin Finck  *           SetDefaultCommConfigA     (KERNEL32.@)
1364c2c66affSColin Finck  *
1365c2c66affSColin Finck  * Initializes the default configuration for a communication device.
1366c2c66affSColin Finck  *
1367c2c66affSColin Finck  * See SetDefaultCommConfigW.
1368c2c66affSColin Finck  *
1369c2c66affSColin Finck  */
SetDefaultCommConfigA(LPCSTR lpszDevice,LPCOMMCONFIG lpCommConfig,DWORD dwSize)1370c2c66affSColin Finck BOOL WINAPI SetDefaultCommConfigA(LPCSTR lpszDevice, LPCOMMCONFIG lpCommConfig, DWORD dwSize)
1371c2c66affSColin Finck {
1372c2c66affSColin Finck     BOOL r;
1373c2c66affSColin Finck     LPWSTR lpDeviceW = NULL;
1374c2c66affSColin Finck     DWORD len;
1375c2c66affSColin Finck 
1376c2c66affSColin Finck     TRACE("(%s, %p, %u)\n", debugstr_a(lpszDevice), lpCommConfig, dwSize);
1377c2c66affSColin Finck 
1378c2c66affSColin Finck     if (lpszDevice)
1379c2c66affSColin Finck     {
1380c2c66affSColin Finck         len = MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, NULL, 0 );
1381c2c66affSColin Finck         lpDeviceW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1382c2c66affSColin Finck         MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, lpDeviceW, len );
1383c2c66affSColin Finck     }
1384c2c66affSColin Finck     r = SetDefaultCommConfigW(lpDeviceW,lpCommConfig,dwSize);
1385c2c66affSColin Finck     HeapFree( GetProcessHeap(), 0, lpDeviceW );
1386c2c66affSColin Finck     return r;
1387c2c66affSColin Finck }
1388c2c66affSColin Finck 
1389c2c66affSColin Finck 
1390c2c66affSColin Finck /***********************************************************************
1391c2c66affSColin Finck  *           GetDefaultCommConfigW   (KERNEL32.@)
1392c2c66affSColin Finck  *
1393c2c66affSColin Finck  *   Acquires the default configuration of the specified communication device. (unicode)
1394c2c66affSColin Finck  *
1395c2c66affSColin Finck  *  RETURNS
1396c2c66affSColin Finck  *
1397c2c66affSColin Finck  *   True on successful reading of the default configuration,
1398c2c66affSColin Finck  *   if the device is not found or the buffer is too small.
1399c2c66affSColin Finck  */
GetDefaultCommConfigW(LPCWSTR lpszName,LPCOMMCONFIG lpCC,LPDWORD lpdwSize)1400c2c66affSColin Finck BOOL WINAPI GetDefaultCommConfigW(
1401c2c66affSColin Finck     LPCWSTR      lpszName, /* [in] The unicode name of the device targeted for configuration. */
1402c2c66affSColin Finck     LPCOMMCONFIG lpCC,     /* [out] The default configuration for the device. */
1403c2c66affSColin Finck     LPDWORD      lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
1404c2c66affSColin Finck                               afterwards the number of bytes copied to the buffer or
1405c2c66affSColin Finck                               the needed size of the buffer. */
1406c2c66affSColin Finck {
1407c2c66affSColin Finck     DWORD (WINAPI *pGetDefaultCommConfig)(LPCWSTR, LPCOMMCONFIG, LPDWORD);
1408c2c66affSColin Finck     HMODULE hConfigModule;
1409c2c66affSColin Finck     DWORD   res = ERROR_INVALID_PARAMETER;
1410c2c66affSColin Finck 
1411c2c66affSColin Finck     TRACE("(%s, %p, %p)  *lpdwSize: %u\n", debugstr_w(lpszName), lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 );
1412c2c66affSColin Finck     hConfigModule = LoadLibraryW(lpszSerialUI);
1413c2c66affSColin Finck 
1414c2c66affSColin Finck     if (hConfigModule) {
1415c2c66affSColin Finck         pGetDefaultCommConfig = (void *)GetProcAddress(hConfigModule, "drvGetDefaultCommConfigW");
1416c2c66affSColin Finck         if (pGetDefaultCommConfig) {
1417c2c66affSColin Finck             res = pGetDefaultCommConfig(lpszName, lpCC, lpdwSize);
1418c2c66affSColin Finck         }
1419c2c66affSColin Finck         FreeLibrary(hConfigModule);
1420c2c66affSColin Finck     }
1421c2c66affSColin Finck 
1422c2c66affSColin Finck     if (res) SetLastError(res);
1423c2c66affSColin Finck     return (res == ERROR_SUCCESS);
1424c2c66affSColin Finck }
1425c2c66affSColin Finck 
1426c2c66affSColin Finck /**************************************************************************
1427c2c66affSColin Finck  *         GetDefaultCommConfigA		(KERNEL32.@)
1428c2c66affSColin Finck  *
1429c2c66affSColin Finck  *   Acquires the default configuration of the specified communication device. (ascii)
1430c2c66affSColin Finck  *
1431c2c66affSColin Finck  *  RETURNS
1432c2c66affSColin Finck  *
1433c2c66affSColin Finck  *   True on successful reading of the default configuration,
1434c2c66affSColin Finck  *   if the device is not found or the buffer is too small.
1435c2c66affSColin Finck  */
GetDefaultCommConfigA(LPCSTR lpszName,LPCOMMCONFIG lpCC,LPDWORD lpdwSize)1436c2c66affSColin Finck BOOL WINAPI GetDefaultCommConfigA(
1437c2c66affSColin Finck     LPCSTR       lpszName, /* [in] The ascii name of the device targeted for configuration. */
1438c2c66affSColin Finck     LPCOMMCONFIG lpCC,     /* [out] The default configuration for the device. */
1439c2c66affSColin Finck     LPDWORD      lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
1440c2c66affSColin Finck 			      afterwards the number of bytes copied to the buffer or
1441c2c66affSColin Finck                               the needed size of the buffer. */
1442c2c66affSColin Finck {
1443c2c66affSColin Finck 	BOOL ret = FALSE;
1444c2c66affSColin Finck 	UNICODE_STRING lpszNameW;
1445c2c66affSColin Finck 
1446c2c66affSColin Finck 	TRACE("(%s, %p, %p)  *lpdwSize: %u\n", debugstr_a(lpszName), lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 );
1447c2c66affSColin Finck 	if(lpszName) RtlCreateUnicodeStringFromAsciiz(&lpszNameW,lpszName);
1448c2c66affSColin Finck 	else lpszNameW.Buffer = NULL;
1449c2c66affSColin Finck 
1450c2c66affSColin Finck 	ret = GetDefaultCommConfigW(lpszNameW.Buffer,lpCC,lpdwSize);
1451c2c66affSColin Finck 
1452c2c66affSColin Finck 	RtlFreeUnicodeString(&lpszNameW);
1453c2c66affSColin Finck 	return ret;
1454c2c66affSColin Finck }
1455