Sync to trunk (r44371)
[reactos.git] / reactos / dll / win32 / kernel32 / misc / comm.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/misc/comm.c
5 * PURPOSE: Comm functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * modified from WINE [ Onno Hovers, (onno@stack.urc.tue.nl) ]
8 * Robert Dickenson (robd@mok.lvcom.com)
9 * Saveliy Tretiakov (saveliyt@mail.ru)
10 * Dmitry Philippov (shedon@mail.ru)
11 * UPDATE HISTORY:
12 * Created 01/11/98
13 * RDD (30/09/2002) implemented many function bodies to call serial driver.
14 * KJK (11/02/2003) implemented BuildCommDCB & BuildCommDCBAndTimeouts
15 * ST (21/03/2005) implemented GetCommProperties
16 * ST (24/03/2005) implemented ClearCommError. Corrected many functions.
17 * ST (05/04/2005) implemented CommConfigDialog
18 * DP (11/06/2005) implemented GetCommConfig
19 * DP (12/06/2005) implemented SetCommConfig
20 * KJK (26/12/2008) reimplemented BuildCommDCB & BuildCommDCBAndTimeouts elsewhere
21 *
22 */
23
24 #include <k32.h>
25 #undef SERIAL_LSRMST_ESCAPE
26 #undef SERIAL_LSRMST_LSR_DATA
27 #undef SERIAL_LSRMST_LSR_NODATA
28 #undef SERIAL_LSRMST_MST
29 #undef SERIAL_IOC_FCR_FIFO_ENABLE
30 #undef SERIAL_IOC_FCR_RCVR_RESET
31 #undef SERIAL_IOC_FCR_XMIT_RESET
32 #undef SERIAL_IOC_FCR_DMA_MODE
33 #undef SERIAL_IOC_FCR_RES1
34 #undef SERIAL_IOC_FCR_RES2
35 #undef SERIAL_IOC_FCR_RCVR_TRIGGER_LSB
36 #undef SERIAL_IOC_FCR_RCVR_TRIGGER_MSB
37 #undef SERIAL_IOC_MCR_DTR
38 #undef SERIAL_IOC_MCR_RTS
39 #undef SERIAL_IOC_MCR_OUT1
40 #undef SERIAL_IOC_MCR_OUT2
41 #undef SERIAL_IOC_MCR_LOOP
42 #undef IOCTL_SERIAL_LSRMST_INSERT
43 #include <ntddser.h>
44
45 #define NDEBUG
46 #include <debug.h>
47
48 static const WCHAR lpszSerialUI[] = {
49 's','e','r','i','a','l','u','i','.','d','l','l',0 };
50
51 /*
52 * @implemented
53 */
54 BOOL
55 WINAPI
56 ClearCommBreak(HANDLE hFile)
57 {
58 DWORD dwBytesReturned;
59 return DeviceIoControl(hFile, IOCTL_SERIAL_SET_BREAK_OFF,
60 NULL, 0, NULL, 0, &dwBytesReturned, NULL);
61 }
62
63
64 /*
65 * @implemented
66 */
67 BOOL
68 WINAPI
69 ClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpComStat)
70 {
71 BOOL status = FALSE;
72 DWORD dwBytesReturned;
73 SERIAL_STATUS SerialStatus;
74
75 status = DeviceIoControl(hFile, IOCTL_SERIAL_GET_COMMSTATUS, NULL, 0,
76 &SerialStatus, sizeof(SERIAL_STATUS), &dwBytesReturned, NULL);
77
78 if(!NT_SUCCESS(status))
79 {
80 return status;
81 }
82
83 if(lpErrors)
84 {
85 *lpErrors = 0;
86 if(SerialStatus.Errors & SERIAL_ERROR_BREAK)
87 *lpErrors |= CE_BREAK;
88 if(SerialStatus.Errors & SERIAL_ERROR_FRAMING)
89 *lpErrors |= CE_FRAME;
90 if(SerialStatus.Errors & SERIAL_ERROR_OVERRUN)
91 *lpErrors |= CE_OVERRUN;
92 if(SerialStatus.Errors & SERIAL_ERROR_QUEUEOVERRUN )
93 *lpErrors |= CE_RXOVER;
94 if(SerialStatus.Errors & SERIAL_ERROR_PARITY)
95 *lpErrors |= CE_RXPARITY;
96 }
97
98 if (lpComStat)
99 {
100 ZeroMemory(lpComStat, sizeof(COMSTAT));
101
102 if(SerialStatus.HoldReasons & SERIAL_TX_WAITING_FOR_CTS)
103 lpComStat->fCtsHold = TRUE;
104 if(SerialStatus.HoldReasons & SERIAL_TX_WAITING_FOR_DSR)
105 lpComStat->fDsrHold = TRUE;
106 if(SerialStatus.HoldReasons & SERIAL_TX_WAITING_FOR_DCD)
107 lpComStat->fRlsdHold = TRUE;
108 if(SerialStatus.HoldReasons & SERIAL_TX_WAITING_FOR_XON)
109 lpComStat->fXoffHold = TRUE;
110 if(SerialStatus.HoldReasons & SERIAL_TX_WAITING_XOFF_SENT)
111 lpComStat->fXoffSent = TRUE;
112
113 if(SerialStatus.EofReceived)
114 lpComStat->fEof = TRUE;
115
116 if(SerialStatus.WaitForImmediate)
117 lpComStat->fTxim = TRUE;
118
119 lpComStat->cbInQue = SerialStatus.AmountInInQueue;
120 lpComStat->cbOutQue = SerialStatus.AmountInOutQueue;
121 }
122 return TRUE;
123 }
124
125
126 /*
127 * @implemented
128 */
129 BOOL
130 WINAPI
131 CommConfigDialogA(LPCSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC)
132 {
133 PWCHAR NameW;
134 DWORD result;
135
136 /* don't use the static thread buffer so operations in serialui
137 don't overwrite the string */
138 if(!(NameW = FilenameA2W(lpszName, TRUE)))
139 {
140 return FALSE;
141 }
142
143 result = CommConfigDialogW(NameW, hWnd, lpCC);
144
145 RtlFreeHeap(RtlGetProcessHeap(), 0, NameW);
146
147 return result;
148 }
149
150
151 /*
152 * @implemented
153 */
154 BOOL
155 WINAPI
156 CommConfigDialogW(LPCWSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC)
157 {
158 DWORD (WINAPI *drvCommDlgW)(LPCWSTR, HWND, LPCOMMCONFIG);
159 HMODULE hSerialuiDll;
160 DWORD result;
161
162 //FIXME: Get dll name from registry. (setupapi needed)
163 if(!(hSerialuiDll = LoadLibraryW(L"serialui.dll")))
164 {
165 DPRINT("CommConfigDialogW: serialui.dll not found.\n");
166 return FALSE;
167 }
168
169 drvCommDlgW = (DWORD (WINAPI *)(LPCWSTR, HWND, LPCOMMCONFIG))
170 GetProcAddress(hSerialuiDll, "drvCommConfigDialogW");
171
172 if(!drvCommDlgW)
173 {
174 DPRINT("CommConfigDialogW: serialui does not export drvCommConfigDialogW\n");
175 FreeLibrary(hSerialuiDll);
176 return FALSE;
177 }
178
179 result = drvCommDlgW(lpszName, hWnd, lpCC);
180 SetLastError(result);
181 FreeLibrary(hSerialuiDll);
182
183 return (result == ERROR_SUCCESS ? TRUE : FALSE);
184 }
185
186
187 /*
188 * @implemented
189 */
190 BOOL
191 WINAPI
192 EscapeCommFunction(HANDLE hFile, DWORD dwFunc)
193 {
194 BOOL result = FALSE;
195 DWORD dwBytesReturned;
196
197 switch (dwFunc) {
198 case CLRDTR: // Clears the DTR (data-terminal-ready) signal.
199 result = DeviceIoControl(hFile, IOCTL_SERIAL_CLR_DTR, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
200 break;
201 case CLRRTS: // Clears the RTS (request-to-send) signal.
202 result = DeviceIoControl(hFile, IOCTL_SERIAL_CLR_RTS, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
203 break;
204 case SETDTR: // Sends the DTR (data-terminal-ready) signal.
205 result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_DTR, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
206 break;
207 case SETRTS: // Sends the RTS (request-to-send) signal.
208 result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_RTS, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
209 break;
210 case SETXOFF: // Causes transmission to act as if an XOFF character has been received.
211 result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_XOFF, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
212 break;
213 case SETXON: // Causes transmission to act as if an XON character has been received.
214 result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_XON, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
215 break;
216 case SETBREAK: // Suspends character transmission and places the transmission line in a break state until the ClearCommBreak function is called (or EscapeCommFunction is called with the CLRBREAK extended function code). The SETBREAK extended function code is identical to the SetCommBreak function. Note that this extended function does not flush data that has not been transmitted.
217 result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_BREAK_ON, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
218 break;
219 case CLRBREAK: // Restores character transmission and places the transmission line in a nonbreak state. The CLRBREAK extended function code is identical to the ClearCommBreak function.
220 result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_BREAK_OFF, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
221 break;
222 default:
223 DPRINT("EscapeCommFunction() WARNING: unknown function code\n");
224 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
225 break;
226 }
227 return result;
228 }
229
230
231 /*
232 * @implemented
233 */
234 BOOL
235 WINAPI
236 GetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, LPDWORD lpdwSize)
237 {
238 BOOL ReturnValue = FALSE;
239 LPCOMMPROP lpComPort;
240
241 DPRINT("GetCommConfig(%d, %p, %p)\n", hCommDev, lpCC, lpdwSize);
242
243 lpComPort = RtlAllocateHeap( hProcessHeap,
244 HEAP_ZERO_MEMORY,
245 sizeof(COMMPROP) + 0x100 );
246
247 if(NULL == lpComPort) {
248 DPRINT("GetCommConfig() - ERROR_NOT_ENOUGH_MEMORY\n");
249 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
250 return FALSE;
251 }
252
253 if( (NULL == lpdwSize)
254 || (NULL == lpCC) ) {
255 DPRINT("GetCommConfig() - invalid parameter\n");
256 SetLastError(ERROR_INVALID_PARAMETER);
257 ReturnValue = FALSE;
258 }
259 else
260 {
261 lpComPort->wPacketLength = sizeof(COMMPROP) + 0x100;
262 lpComPort->dwProvSpec1 = COMMPROP_INITIALIZED;
263 ReturnValue = GetCommProperties(hCommDev, lpComPort);
264 if( ReturnValue )
265 {
266 lpCC->dwSize = sizeof(COMMCONFIG);
267 lpCC->wVersion = 1;
268 lpCC->wReserved = 0;
269 lpCC->dwProviderSubType = lpComPort->dwProvSubType;
270 lpCC->dwProviderSize = lpComPort->dwProvSpec2;
271 if( 0 == lpComPort->dwProvSpec2 ) {
272 lpCC->dwProviderOffset = 0;
273 } else {
274 lpCC->dwProviderOffset = (ULONG_PTR)&lpCC->wcProviderData[0] - (ULONG_PTR)lpCC;
275 }
276 if( (lpCC->dwProviderSize+lpCC->dwSize) > *lpdwSize ) {
277 DPRINT("GetCommConfig() - ERROR_INSUFFICIENT_BUFFER\n");
278 SetLastError(ERROR_INSUFFICIENT_BUFFER);
279 ReturnValue = FALSE;
280 } else {
281 RtlCopyMemory(lpCC->wcProviderData, lpComPort->wcProvChar, lpCC->dwProviderSize);
282 ReturnValue = GetCommState(hCommDev, &lpCC->dcb);
283 }
284 *lpdwSize = lpCC->dwSize+lpCC->dwProviderSize;
285 }
286 }
287
288 RtlFreeHeap(hProcessHeap, 0, lpComPort);
289 return (ReturnValue);
290 }
291
292
293 /*
294 * @implemented
295 */
296 BOOL
297 WINAPI
298 GetCommMask(HANDLE hFile, LPDWORD lpEvtMask)
299 {
300 DWORD dwBytesReturned;
301 return DeviceIoControl(hFile, IOCTL_SERIAL_GET_WAIT_MASK,
302 NULL, 0, lpEvtMask, sizeof(DWORD), &dwBytesReturned, NULL);
303 }
304
305
306 /*
307 * @implemented
308 */
309 BOOL
310 WINAPI
311 GetCommModemStatus(HANDLE hFile, LPDWORD lpModemStat)
312 {
313 DWORD dwBytesReturned;
314
315 return DeviceIoControl(hFile, IOCTL_SERIAL_GET_MODEMSTATUS,
316 NULL, 0, lpModemStat, sizeof(DWORD), &dwBytesReturned, NULL);
317 }
318
319
320 /*
321 * @implemented
322 */
323 BOOL
324 WINAPI
325 GetCommProperties(HANDLE hFile, LPCOMMPROP lpCommProp)
326 {
327 DWORD dwBytesReturned;
328 return DeviceIoControl(hFile, IOCTL_SERIAL_GET_PROPERTIES, 0, 0,
329 lpCommProp, sizeof(COMMPROP), &dwBytesReturned, 0);
330 }
331
332
333 /*
334 * @implemented
335 */
336 BOOL
337 WINAPI
338 GetCommState(HANDLE hFile, LPDCB lpDCB)
339 {
340 BOOL result = FALSE;
341 DWORD dwBytesReturned;
342
343 SERIAL_BAUD_RATE BaudRate;
344 SERIAL_HANDFLOW HandFlow;
345 SERIAL_CHARS SpecialChars;
346 SERIAL_LINE_CONTROL LineControl;
347
348 DPRINT("GetCommState(%d, %p)\n", hFile, lpDCB);
349
350 if (lpDCB == NULL) {
351 SetLastError(ERROR_INVALID_PARAMETER);
352 DPRINT("ERROR: GetCommState() - NULL DCB pointer\n");
353 return FALSE;
354 }
355
356 if (!DeviceIoControl(hFile, IOCTL_SERIAL_GET_BAUD_RATE,
357 NULL, 0, &BaudRate, sizeof(BaudRate), &dwBytesReturned, NULL) ||
358 !DeviceIoControl(hFile, IOCTL_SERIAL_GET_LINE_CONTROL,
359 NULL, 0, &LineControl, sizeof(LineControl), &dwBytesReturned, NULL) ||
360 !DeviceIoControl(hFile, IOCTL_SERIAL_GET_HANDFLOW,
361 NULL, 0, &HandFlow, sizeof(HandFlow), &dwBytesReturned, NULL) ||
362 !DeviceIoControl(hFile, IOCTL_SERIAL_GET_CHARS,
363 NULL, 0, &SpecialChars, sizeof(SpecialChars), &dwBytesReturned, NULL))
364 return FALSE;
365
366 memset(lpDCB, 0, sizeof(*lpDCB));
367 lpDCB->DCBlength = sizeof(*lpDCB);
368
369 lpDCB->fBinary = 1;
370 lpDCB->fParity = 0;
371 lpDCB->BaudRate = BaudRate.BaudRate;
372
373 lpDCB->StopBits = LineControl.StopBits;
374 lpDCB->Parity = LineControl.Parity;
375 lpDCB->ByteSize = LineControl.WordLength;
376
377 if (HandFlow.ControlHandShake & SERIAL_CTS_HANDSHAKE) {
378 lpDCB->fOutxCtsFlow = 1;
379 }
380 if (HandFlow.ControlHandShake & SERIAL_DSR_HANDSHAKE) {
381 lpDCB->fOutxDsrFlow = 1;
382 }
383 if (HandFlow.ControlHandShake & SERIAL_DTR_CONTROL) {
384 lpDCB->fDtrControl = 1;
385 }
386 if (HandFlow.ControlHandShake & SERIAL_DTR_HANDSHAKE) {
387 lpDCB->fDtrControl = 2;
388 }
389 if (HandFlow.ControlHandShake & SERIAL_RTS_CONTROL) {
390 lpDCB->fRtsControl = 1;
391 }
392 if (HandFlow.ControlHandShake & SERIAL_RTS_HANDSHAKE) {
393 lpDCB->fRtsControl = 2;
394 }
395 if (HandFlow.ControlHandShake & SERIAL_DSR_SENSITIVITY) {
396 lpDCB->fDsrSensitivity = 1;
397 }
398 if (HandFlow.ControlHandShake & SERIAL_ERROR_ABORT) {
399 lpDCB->fAbortOnError = 1;
400 }
401
402 if (HandFlow.FlowReplace & SERIAL_ERROR_CHAR) {
403 lpDCB->fErrorChar = 1;
404 }
405 if (HandFlow.FlowReplace & SERIAL_NULL_STRIPPING) {
406 lpDCB->fNull = 1;
407 }
408 if (HandFlow.FlowReplace & SERIAL_XOFF_CONTINUE) {
409 lpDCB->fTXContinueOnXoff = 1;
410 }
411 lpDCB->XonLim = (WORD)HandFlow.XonLimit;
412 lpDCB->XoffLim = (WORD)HandFlow.XoffLimit;
413
414 result = DeviceIoControl(hFile, IOCTL_SERIAL_GET_CHARS,
415 NULL, 0, &SpecialChars, sizeof(SpecialChars), &dwBytesReturned, NULL);
416 if (!NT_SUCCESS(result)) {
417 DPRINT("ERROR: GetCommState() - DeviceIoControl(IOCTL_SERIAL_GET_CHARS) Failed.\n");
418 return FALSE;
419 }
420
421 lpDCB->EofChar = SpecialChars.EofChar;
422 lpDCB->ErrorChar = SpecialChars.ErrorChar;
423 // = SpecialChars.BreakChar;
424 lpDCB->EvtChar = SpecialChars.EventChar;
425 lpDCB->XonChar = SpecialChars.XonChar;
426 lpDCB->XoffChar = SpecialChars.XoffChar;
427
428 result = DeviceIoControl(hFile, IOCTL_SERIAL_GET_LINE_CONTROL,
429 NULL, 0, &LineControl, sizeof(LineControl), &dwBytesReturned, NULL);
430 if (!NT_SUCCESS(result)) {
431 DPRINT("ERROR: GetCommState() - DeviceIoControl(IOCTL_SERIAL_GET_LINE_CONTROL) Failed.\n");
432 return FALSE;
433 }
434 lpDCB->StopBits = LineControl.StopBits;
435 lpDCB->Parity = LineControl.Parity;
436 lpDCB->ByteSize = LineControl.WordLength;
437 DPRINT("GetCommState() - COMPLETED SUCCESSFULLY\n");
438 return TRUE;
439 }
440
441
442 /*
443 * @implemented
444 */
445 BOOL
446 WINAPI
447 GetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts)
448 {
449 DWORD dwBytesReturned;
450
451 if (lpCommTimeouts == NULL) {
452 return FALSE;
453 }
454
455 return DeviceIoControl(hFile, IOCTL_SERIAL_GET_TIMEOUTS,
456 NULL, 0,
457 lpCommTimeouts, sizeof(COMMTIMEOUTS),
458 &dwBytesReturned, NULL);
459 }
460
461
462 /*
463 * @implemented
464 */
465 BOOL
466 WINAPI
467 GetDefaultCommConfigW(LPCWSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize)
468 {
469 FARPROC pGetDefaultCommConfig;
470 HMODULE hConfigModule;
471 DWORD res = ERROR_INVALID_PARAMETER;
472
473 DPRINT("(%s, %p, %p) *lpdwSize: %u\n", lpszName, lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 );
474 hConfigModule = LoadLibraryW(lpszSerialUI);
475
476 if (hConfigModule) {
477 pGetDefaultCommConfig = GetProcAddress(hConfigModule, "drvGetDefaultCommConfigW");
478 if (pGetDefaultCommConfig) {
479 res = pGetDefaultCommConfig(lpszName, lpCC, lpdwSize);
480 }
481 FreeLibrary(hConfigModule);
482 }
483
484 if (res) SetLastError(res);
485 return (res == ERROR_SUCCESS);
486 }
487
488
489 /*
490 * @implemented
491 */
492 BOOL
493 WINAPI
494 GetDefaultCommConfigA(LPCSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize)
495 {
496 BOOL ret = FALSE;
497 UNICODE_STRING lpszNameW;
498
499 DPRINT("(%s, %p, %p) *lpdwSize: %u\n", lpszName, lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 );
500 if(lpszName) RtlCreateUnicodeStringFromAsciiz(&lpszNameW,lpszName);
501 else lpszNameW.Buffer = NULL;
502
503 ret = GetDefaultCommConfigW(lpszNameW.Buffer,lpCC,lpdwSize);
504
505 RtlFreeUnicodeString(&lpszNameW);
506 return ret;
507 }
508
509
510 /*
511 * @implemented
512 */
513 BOOL
514 WINAPI
515 PurgeComm(HANDLE hFile, DWORD dwFlags)
516 {
517 DWORD dwBytesReturned;
518
519 return DeviceIoControl(hFile, IOCTL_SERIAL_PURGE,
520 &dwFlags, sizeof(DWORD), NULL, 0, &dwBytesReturned, NULL);
521 }
522
523
524 /*
525 * @implemented
526 */
527 BOOL
528 WINAPI
529 SetCommBreak(HANDLE hFile)
530 {
531 DWORD dwBytesReturned;
532
533 return DeviceIoControl(hFile, IOCTL_SERIAL_SET_BREAK_ON, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
534 }
535
536
537 /*
538 * @implemented
539 */
540 BOOL
541 WINAPI
542 SetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, DWORD dwSize)
543 {
544 BOOL ReturnValue = FALSE;
545
546 DPRINT("SetCommConfig(%d, %p, %d)\n", hCommDev, lpCC, dwSize);
547
548 if(NULL == lpCC)
549 {
550 DPRINT("SetCommConfig() - invalid parameter\n");
551 SetLastError(ERROR_INVALID_PARAMETER);
552 ReturnValue = FALSE;
553 }
554 else
555 {
556 ReturnValue = SetCommState(hCommDev, &lpCC->dcb);
557 }
558
559 return ReturnValue;
560 }
561
562
563 /*
564 * @implemented
565 */
566 BOOL
567 WINAPI
568 SetCommMask(HANDLE hFile, DWORD dwEvtMask)
569 {
570 DWORD dwBytesReturned;
571
572 return DeviceIoControl(hFile, IOCTL_SERIAL_SET_WAIT_MASK,
573 &dwEvtMask, sizeof(DWORD), NULL, 0, &dwBytesReturned, NULL);
574 }
575
576
577 /*
578 * @implemented
579 */
580 BOOL
581 WINAPI
582 SetCommState(HANDLE hFile, LPDCB lpDCB)
583 {
584 BOOL result = FALSE;
585 DWORD dwBytesReturned;
586
587 SERIAL_BAUD_RATE BaudRate;
588 SERIAL_HANDFLOW HandFlow;
589 SERIAL_CHARS SpecialChars;
590 SERIAL_LINE_CONTROL LineControl;
591
592 DPRINT("SetCommState(%d, %p) - ENTERED\n", hFile, lpDCB);
593
594 if (lpDCB == NULL) {
595 DPRINT("SetCommState() - ERROR: NULL DCB pointer passed\n");
596 return FALSE;
597 }
598
599 BaudRate.BaudRate = lpDCB->BaudRate;
600 result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_BAUD_RATE,
601 &BaudRate, sizeof(BaudRate), NULL, 0, &dwBytesReturned, NULL);
602 if (!NT_SUCCESS(result)) {
603 DPRINT("ERROR: SetCommState() - DeviceIoControl(IOCTL_SERIAL_SET_BAUD_RATE) Failed.\n");
604 return FALSE;
605 }
606 /*
607 #define SERIAL_DTR_MASK ((ULONG)0x03)
608 #define SERIAL_DTR_CONTROL ((ULONG)0x01)
609 #define SERIAL_DTR_HANDSHAKE ((ULONG)0x02)
610 #define SERIAL_CTS_HANDSHAKE ((ULONG)0x08)
611 #define SERIAL_DSR_HANDSHAKE ((ULONG)0x10)
612 #define SERIAL_DCD_HANDSHAKE ((ULONG)0x20)
613 #define SERIAL_OUT_HANDSHAKEMASK ((ULONG)0x38)
614 #define SERIAL_DSR_SENSITIVITY ((ULONG)0x40)
615 #define SERIAL_ERROR_ABORT ((ULONG)0x80000000)
616 #define SERIAL_CONTROL_INVALID ((ULONG)0x7fffff84)
617 */
618 HandFlow.ControlHandShake = 0;
619
620 if (lpDCB->fOutxCtsFlow) {
621 HandFlow.ControlHandShake |= SERIAL_CTS_HANDSHAKE;
622 }
623 if (lpDCB->fOutxDsrFlow) {
624 HandFlow.ControlHandShake |= SERIAL_DSR_HANDSHAKE;
625 }
626 if (lpDCB->fDtrControl) {
627 HandFlow.ControlHandShake |= SERIAL_DTR_CONTROL;
628 }
629 if (lpDCB->fDtrControl) {
630 HandFlow.ControlHandShake |= SERIAL_DTR_HANDSHAKE;
631 }
632 if (lpDCB->fRtsControl) {
633 HandFlow.ControlHandShake |= SERIAL_RTS_CONTROL;
634 }
635 if (lpDCB->fRtsControl) {
636 HandFlow.ControlHandShake |= SERIAL_RTS_HANDSHAKE;
637 }
638 if (lpDCB->fDsrSensitivity) {
639 HandFlow.ControlHandShake |= SERIAL_DSR_SENSITIVITY;
640 }
641 if (lpDCB->fAbortOnError) {
642 HandFlow.ControlHandShake |= SERIAL_ERROR_ABORT;
643 }
644 /*
645 #define SERIAL_AUTO_TRANSMIT ((ULONG)0x01)
646 #define SERIAL_AUTO_RECEIVE ((ULONG)0x02)
647 #define SERIAL_ERROR_CHAR ((ULONG)0x04)
648 #define SERIAL_NULL_STRIPPING ((ULONG)0x08)
649 #define SERIAL_BREAK_CHAR ((ULONG)0x10)
650 #define SERIAL_RTS_MASK ((ULONG)0xc0)
651 #define SERIAL_RTS_CONTROL ((ULONG)0x40)
652 #define SERIAL_RTS_HANDSHAKE ((ULONG)0x80)
653 #define SERIAL_TRANSMIT_TOGGLE ((ULONG)0xc0)
654 #define SERIAL_XOFF_CONTINUE ((ULONG)0x80000000)
655 #define SERIAL_FLOW_INVALID ((ULONG)0x7fffff20)
656 */
657 HandFlow.FlowReplace = 0;
658 if (lpDCB->fErrorChar) {
659 HandFlow.FlowReplace |= SERIAL_ERROR_CHAR;
660 }
661 if (lpDCB->fNull) {
662 HandFlow.FlowReplace |= SERIAL_NULL_STRIPPING;
663 }
664 if (lpDCB->fTXContinueOnXoff) {
665 HandFlow.FlowReplace |= SERIAL_XOFF_CONTINUE;
666 }
667 HandFlow.XonLimit = lpDCB->XonLim;
668 HandFlow.XoffLimit = lpDCB->XoffLim;
669 result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_HANDFLOW,
670 &HandFlow, sizeof(HandFlow), NULL, 0, &dwBytesReturned, NULL);
671 if (!NT_SUCCESS(result)) {
672 DPRINT("ERROR: SetCommState() - DeviceIoControl(IOCTL_SERIAL_SET_HANDFLOW) Failed.\n");
673 return FALSE;
674 }
675
676 SpecialChars.EofChar = lpDCB->EofChar;
677 SpecialChars.ErrorChar = lpDCB->ErrorChar;
678 SpecialChars.BreakChar = 0;
679 SpecialChars.EventChar = lpDCB->EvtChar;
680 SpecialChars.XonChar = lpDCB->XonChar;
681 SpecialChars.XoffChar = lpDCB->XoffChar;
682 result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_CHARS,
683 &SpecialChars, sizeof(SpecialChars), NULL, 0, &dwBytesReturned, NULL);
684 if (!NT_SUCCESS(result)) {
685 DPRINT("ERROR: SetCommState() - DeviceIoControl(IOCTL_SERIAL_SET_CHARS) Failed.\n");
686 return FALSE;
687 }
688
689 LineControl.StopBits = lpDCB->StopBits;
690 LineControl.Parity = lpDCB->Parity;
691 LineControl.WordLength = lpDCB->ByteSize;
692 result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_LINE_CONTROL,
693 &LineControl, sizeof(LineControl), NULL, 0, &dwBytesReturned, NULL);
694 if (!NT_SUCCESS(result)) {
695 DPRINT("ERROR: SetCommState() - DeviceIoControl(IOCTL_SERIAL_SET_LINE_CONTROL) Failed.\n");
696 return FALSE;
697 }
698
699 DPRINT("SetCommState() - COMPLETED SUCCESSFULLY\n");
700 return TRUE;
701 }
702
703
704 /*
705 * @implemented
706 */
707 BOOL
708 WINAPI
709 SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts)
710 {
711 DWORD dwBytesReturned;
712 SERIAL_TIMEOUTS Timeouts;
713
714 if (lpCommTimeouts == NULL) {
715 return FALSE;
716 }
717 Timeouts.ReadIntervalTimeout = lpCommTimeouts->ReadIntervalTimeout;
718 Timeouts.ReadTotalTimeoutMultiplier = lpCommTimeouts->ReadTotalTimeoutMultiplier;
719 Timeouts.ReadTotalTimeoutConstant = lpCommTimeouts->ReadTotalTimeoutConstant;
720 Timeouts.WriteTotalTimeoutMultiplier = lpCommTimeouts->WriteTotalTimeoutMultiplier;
721 Timeouts.WriteTotalTimeoutConstant = lpCommTimeouts->WriteTotalTimeoutConstant;
722
723 return DeviceIoControl(hFile, IOCTL_SERIAL_SET_TIMEOUTS,
724 &Timeouts, sizeof(Timeouts), NULL, 0, &dwBytesReturned, NULL);
725 }
726
727
728 /*
729 * @implemented
730 */
731 BOOL
732 WINAPI
733 SetDefaultCommConfigA(LPCSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize)
734 {
735 BOOL r;
736 LPWSTR lpDeviceW = NULL;
737 DWORD len;
738
739 DPRINT("(%s, %p, %u)\n", lpszName, lpCC, dwSize);
740
741 if (lpszName)
742 {
743 len = MultiByteToWideChar( CP_ACP, 0, lpszName, -1, NULL, 0 );
744
745 lpDeviceW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
746 if (!lpDeviceW)
747 {
748 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
749 return FALSE;
750 }
751
752 MultiByteToWideChar( CP_ACP, 0, lpszName, -1, lpDeviceW, len );
753 }
754 r = SetDefaultCommConfigW(lpDeviceW,lpCC,dwSize);
755 HeapFree( GetProcessHeap(), 0, lpDeviceW );
756 return r;
757 }
758
759
760 /*
761 * @implemented
762 */
763 BOOL
764 WINAPI
765 SetDefaultCommConfigW(LPCWSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize)
766 {
767 FARPROC pGetDefaultCommConfig;
768 HMODULE hConfigModule;
769 DWORD res = ERROR_INVALID_PARAMETER;
770
771 DPRINT("(%s, %p, %p) *dwSize: %u\n", lpszName, lpCC, dwSize, dwSize ? dwSize : 0 );
772 hConfigModule = LoadLibraryW(lpszSerialUI);
773
774 if (hConfigModule) {
775 pGetDefaultCommConfig = GetProcAddress(hConfigModule, "drvGetDefaultCommConfigW");
776 if (pGetDefaultCommConfig) {
777 res = pGetDefaultCommConfig(lpszName, lpCC, &dwSize);
778 }
779 FreeLibrary(hConfigModule);
780 }
781
782 if (res) SetLastError(res);
783 return (res == ERROR_SUCCESS);
784 }
785
786
787 /*
788 * @implemented
789 */
790 BOOL
791 WINAPI
792 SetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue)
793 {
794 DWORD dwBytesReturned;
795 SERIAL_QUEUE_SIZE QueueSize;
796
797 QueueSize.InSize = dwInQueue;
798 QueueSize.OutSize = dwOutQueue;
799 return DeviceIoControl(hFile, IOCTL_SERIAL_SET_QUEUE_SIZE,
800 &QueueSize, sizeof(QueueSize), NULL, 0, &dwBytesReturned, NULL);
801 }
802
803
804 /*
805 * @implemented
806 */
807 BOOL
808 WINAPI
809 TransmitCommChar(HANDLE hFile, char cChar)
810 {
811 DWORD dwBytesReturned;
812 return DeviceIoControl(hFile, IOCTL_SERIAL_IMMEDIATE_CHAR,
813 &cChar, sizeof(cChar), NULL, 0, &dwBytesReturned, NULL);
814 }
815
816
817 /*
818 * @implemented
819 */
820 BOOL
821 WINAPI
822 WaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped)
823 {
824 DWORD dwBytesReturned;
825
826 if (lpEvtMask == NULL) {
827 return FALSE;
828 }
829
830 return DeviceIoControl(hFile, IOCTL_SERIAL_WAIT_ON_MASK,
831 NULL, 0, lpEvtMask, sizeof(DWORD), &dwBytesReturned, lpOverlapped);
832 }
833
834 /* EOF */