Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencomm.c
Go to the documentation of this file.
00001 /* 00002 * DEC 93 Erik Bos <erik@xs4all.nl> 00003 * 00004 * Copyright 1996 Marcus Meissner 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 //#include "config.h" 00022 //#include "wine/port.h" 00023 00024 #include <stdlib.h> 00025 #include <stdarg.h> 00026 #include <stdio.h> 00027 00028 #define NONAMELESSUNION 00029 #define NONAMELESSSTRUCT 00030 #include "windef.h" 00031 #include "winbase.h" 00032 #include "winerror.h" 00033 #include "winioctl.h" 00034 #include "winternl.h" 00035 //#include "ddk/ntddser.h" 00036 00037 typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; 00038 #undef SERIAL_LSRMST_ESCAPE 00039 #undef SERIAL_LSRMST_LSR_DATA 00040 #undef SERIAL_LSRMST_LSR_NODATA 00041 #undef SERIAL_LSRMST_MST 00042 #undef SERIAL_IOC_FCR_FIFO_ENABLE 00043 #undef SERIAL_IOC_FCR_RCVR_RESET 00044 #undef SERIAL_IOC_FCR_XMIT_RESET 00045 #undef SERIAL_IOC_FCR_DMA_MODE 00046 #undef SERIAL_IOC_FCR_RES1 00047 #undef SERIAL_IOC_FCR_RES2 00048 #undef SERIAL_IOC_FCR_RCVR_TRIGGER_LSB 00049 #undef SERIAL_IOC_FCR_RCVR_TRIGGER_MSB 00050 #undef SERIAL_IOC_MCR_DTR 00051 #undef SERIAL_IOC_MCR_RTS 00052 #undef SERIAL_IOC_MCR_OUT1 00053 #undef SERIAL_IOC_MCR_OUT2 00054 #undef SERIAL_IOC_MCR_LOOP 00055 #undef IOCTL_SERIAL_LSRMST_INSERT 00056 #include <ntddser.h> 00057 00058 #include "wine/unicode.h" 00059 00060 #include "wine/debug.h" 00061 00062 #define HeapAlloc RtlAllocateHeap 00063 #define HeapReAlloc RtlReAllocateHeap 00064 #define HeapFree RtlFreeHeap 00065 WINE_DEFAULT_DEBUG_CHANNEL(comm); 00066 00067 /*********************************************************************** 00068 * COMM_Parse* (Internal) 00069 * 00070 * The following COMM_Parse* functions are used by the BuildCommDCB 00071 * functions to help parse the various parts of the device control string. 00072 */ 00073 static LPCWSTR COMM_ParseStart(LPCWSTR ptr) 00074 { 00075 static const WCHAR comW[] = {'C','O','M',0}; 00076 00077 /* The device control string may optionally start with "COMx" followed 00078 by an optional ':' and spaces. */ 00079 if(!strncmpiW(ptr, comW, 3)) 00080 { 00081 ptr += 3; 00082 00083 /* Allow any com port above 0 as Win 9x does (NT only allows 00084 values for com ports which are actually present) */ 00085 if(*ptr < '1' || *ptr > '9') 00086 return NULL; 00087 00088 /* Advance pointer past port number */ 00089 while(*ptr >= '0' && *ptr <= '9') ptr++; 00090 00091 /* The com port number must be followed by a ':' or ' ' */ 00092 if(*ptr != ':' && *ptr != ' ') 00093 return NULL; 00094 00095 /* Advance pointer to beginning of next parameter */ 00096 while(*ptr == ' ') ptr++; 00097 if(*ptr == ':') 00098 { 00099 ptr++; 00100 while(*ptr == ' ') ptr++; 00101 } 00102 } 00103 /* The device control string must not start with a space. */ 00104 else if(*ptr == ' ') 00105 return NULL; 00106 00107 return ptr; 00108 } 00109 00110 static LPCWSTR COMM_ParseNumber(LPCWSTR ptr, LPDWORD lpnumber) 00111 { 00112 if(*ptr < '0' || *ptr > '9') return NULL; 00113 *lpnumber = strtoulW(ptr, NULL, 10); 00114 while(*ptr >= '0' && *ptr <= '9') ptr++; 00115 return ptr; 00116 } 00117 00118 static LPCWSTR COMM_ParseParity(LPCWSTR ptr, LPBYTE lpparity) 00119 { 00120 /* Contrary to what you might expect, Windows only sets the Parity 00121 member of DCB and not fParity even when parity is specified in the 00122 device control string */ 00123 00124 switch(toupperW(*ptr++)) 00125 { 00126 case 'E': 00127 *lpparity = EVENPARITY; 00128 break; 00129 case 'M': 00130 *lpparity = MARKPARITY; 00131 break; 00132 case 'N': 00133 *lpparity = NOPARITY; 00134 break; 00135 case 'O': 00136 *lpparity = ODDPARITY; 00137 break; 00138 case 'S': 00139 *lpparity = SPACEPARITY; 00140 break; 00141 default: 00142 return NULL; 00143 } 00144 00145 return ptr; 00146 } 00147 00148 static LPCWSTR COMM_ParseByteSize(LPCWSTR ptr, LPBYTE lpbytesize) 00149 { 00150 DWORD temp; 00151 00152 if(!(ptr = COMM_ParseNumber(ptr, &temp))) 00153 return NULL; 00154 00155 if(temp >= 5 && temp <= 8) 00156 { 00157 *lpbytesize = temp; 00158 return ptr; 00159 } 00160 else 00161 return NULL; 00162 } 00163 00164 static LPCWSTR COMM_ParseStopBits(LPCWSTR ptr, LPBYTE lpstopbits) 00165 { 00166 DWORD temp; 00167 static const WCHAR stopbits15W[] = {'1','.','5',0}; 00168 00169 if(!strncmpW(stopbits15W, ptr, 3)) 00170 { 00171 ptr += 3; 00172 *lpstopbits = ONE5STOPBITS; 00173 } 00174 else 00175 { 00176 if(!(ptr = COMM_ParseNumber(ptr, &temp))) 00177 return NULL; 00178 00179 if(temp == 1) 00180 *lpstopbits = ONESTOPBIT; 00181 else if(temp == 2) 00182 *lpstopbits = TWOSTOPBITS; 00183 else 00184 return NULL; 00185 } 00186 00187 return ptr; 00188 } 00189 00190 static LPCWSTR COMM_ParseOnOff(LPCWSTR ptr, LPDWORD lponoff) 00191 { 00192 static const WCHAR onW[] = {'o','n',0}; 00193 static const WCHAR offW[] = {'o','f','f',0}; 00194 00195 if(!strncmpiW(onW, ptr, 2)) 00196 { 00197 ptr += 2; 00198 *lponoff = 1; 00199 } 00200 else if(!strncmpiW(offW, ptr, 3)) 00201 { 00202 ptr += 3; 00203 *lponoff = 0; 00204 } 00205 else 00206 return NULL; 00207 00208 return ptr; 00209 } 00210 00211 /*********************************************************************** 00212 * COMM_BuildOldCommDCB (Internal) 00213 * 00214 * Build a DCB using the old style settings string eg: "96,n,8,1" 00215 */ 00216 static BOOL COMM_BuildOldCommDCB(LPCWSTR device, LPDCB lpdcb) 00217 { 00218 WCHAR last = 0; 00219 00220 if(!(device = COMM_ParseNumber(device, &lpdcb->BaudRate))) 00221 return FALSE; 00222 00223 switch(lpdcb->BaudRate) 00224 { 00225 case 11: 00226 case 30: 00227 case 60: 00228 lpdcb->BaudRate *= 10; 00229 break; 00230 case 12: 00231 case 24: 00232 case 48: 00233 case 96: 00234 lpdcb->BaudRate *= 100; 00235 break; 00236 case 19: 00237 lpdcb->BaudRate = 19200; 00238 break; 00239 } 00240 00241 while(*device == ' ') device++; 00242 if(*device++ != ',') return FALSE; 00243 while(*device == ' ') device++; 00244 00245 if(!(device = COMM_ParseParity(device, &lpdcb->Parity))) 00246 return FALSE; 00247 00248 while(*device == ' ') device++; 00249 if(*device++ != ',') return FALSE; 00250 while(*device == ' ') device++; 00251 00252 if(!(device = COMM_ParseByteSize(device, &lpdcb->ByteSize))) 00253 return FALSE; 00254 00255 while(*device == ' ') device++; 00256 if(*device++ != ',') return FALSE; 00257 while(*device == ' ') device++; 00258 00259 if(!(device = COMM_ParseStopBits(device, &lpdcb->StopBits))) 00260 return FALSE; 00261 00262 /* The last parameter for flow control is optional. */ 00263 while(*device == ' ') device++; 00264 if(*device == ',') 00265 { 00266 device++; 00267 while(*device == ' ') device++; 00268 if(*device) last = toupperW(*device++); 00269 while(*device == ' ') device++; 00270 } 00271 00272 /* Win NT sets the flow control members based on (or lack of) the last 00273 parameter. Win 9x does not set these members. */ 00274 switch(last) 00275 { 00276 case 0: 00277 lpdcb->fInX = FALSE; 00278 lpdcb->fOutX = FALSE; 00279 lpdcb->fOutxCtsFlow = FALSE; 00280 lpdcb->fOutxDsrFlow = FALSE; 00281 lpdcb->fDtrControl = DTR_CONTROL_ENABLE; 00282 lpdcb->fRtsControl = RTS_CONTROL_ENABLE; 00283 break; 00284 case 'X': 00285 lpdcb->fInX = TRUE; 00286 lpdcb->fOutX = TRUE; 00287 lpdcb->fOutxCtsFlow = FALSE; 00288 lpdcb->fOutxDsrFlow = FALSE; 00289 lpdcb->fDtrControl = DTR_CONTROL_ENABLE; 00290 lpdcb->fRtsControl = RTS_CONTROL_ENABLE; 00291 break; 00292 case 'P': 00293 lpdcb->fInX = FALSE; 00294 lpdcb->fOutX = FALSE; 00295 lpdcb->fOutxCtsFlow = TRUE; 00296 lpdcb->fOutxDsrFlow = TRUE; 00297 lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE; 00298 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE; 00299 break; 00300 default: 00301 return FALSE; 00302 } 00303 00304 /* This should be the end of the string. */ 00305 if(*device) return FALSE; 00306 00307 return TRUE; 00308 } 00309 00310 /*********************************************************************** 00311 * COMM_BuildNewCommDCB (Internal) 00312 * 00313 * Build a DCB using the new style settings string. 00314 * eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on" 00315 */ 00316 static BOOL COMM_BuildNewCommDCB(LPCWSTR device, LPDCB lpdcb, LPCOMMTIMEOUTS lptimeouts) 00317 { 00318 DWORD temp; 00319 BOOL baud = FALSE, stop = FALSE; 00320 static const WCHAR baudW[] = {'b','a','u','d','=',0}; 00321 static const WCHAR parityW[] = {'p','a','r','i','t','y','=',0}; 00322 static const WCHAR dataW[] = {'d','a','t','a','=',0}; 00323 static const WCHAR stopW[] = {'s','t','o','p','=',0}; 00324 static const WCHAR toW[] = {'t','o','=',0}; 00325 static const WCHAR xonW[] = {'x','o','n','=',0}; 00326 static const WCHAR odsrW[] = {'o','d','s','r','=',0}; 00327 static const WCHAR octsW[] = {'o','c','t','s','=',0}; 00328 static const WCHAR dtrW[] = {'d','t','r','=',0}; 00329 static const WCHAR rtsW[] = {'r','t','s','=',0}; 00330 static const WCHAR idsrW[] = {'i','d','s','r','=',0}; 00331 00332 while(*device) 00333 { 00334 while(*device == ' ') device++; 00335 00336 if(!strncmpiW(baudW, device, 5)) 00337 { 00338 baud = TRUE; 00339 00340 if(!(device = COMM_ParseNumber(device + 5, &lpdcb->BaudRate))) 00341 return FALSE; 00342 } 00343 else if(!strncmpiW(parityW, device, 7)) 00344 { 00345 if(!(device = COMM_ParseParity(device + 7, &lpdcb->Parity))) 00346 return FALSE; 00347 } 00348 else if(!strncmpiW(dataW, device, 5)) 00349 { 00350 if(!(device = COMM_ParseByteSize(device + 5, &lpdcb->ByteSize))) 00351 return FALSE; 00352 } 00353 else if(!strncmpiW(stopW, device, 5)) 00354 { 00355 stop = TRUE; 00356 00357 if(!(device = COMM_ParseStopBits(device + 5, &lpdcb->StopBits))) 00358 return FALSE; 00359 } 00360 else if(!strncmpiW(toW, device, 3)) 00361 { 00362 if(!(device = COMM_ParseOnOff(device + 3, &temp))) 00363 return FALSE; 00364 00365 lptimeouts->ReadIntervalTimeout = 0; 00366 lptimeouts->ReadTotalTimeoutMultiplier = 0; 00367 lptimeouts->ReadTotalTimeoutConstant = 0; 00368 lptimeouts->WriteTotalTimeoutMultiplier = 0; 00369 lptimeouts->WriteTotalTimeoutConstant = temp ? 60000 : 0; 00370 } 00371 else if(!strncmpiW(xonW, device, 4)) 00372 { 00373 if(!(device = COMM_ParseOnOff(device + 4, &temp))) 00374 return FALSE; 00375 00376 lpdcb->fOutX = temp; 00377 lpdcb->fInX = temp; 00378 } 00379 else if(!strncmpiW(odsrW, device, 5)) 00380 { 00381 if(!(device = COMM_ParseOnOff(device + 5, &temp))) 00382 return FALSE; 00383 00384 lpdcb->fOutxDsrFlow = temp; 00385 } 00386 else if(!strncmpiW(octsW, device, 5)) 00387 { 00388 if(!(device = COMM_ParseOnOff(device + 5, &temp))) 00389 return FALSE; 00390 00391 lpdcb->fOutxCtsFlow = temp; 00392 } 00393 else if(!strncmpiW(dtrW, device, 4)) 00394 { 00395 if(!(device = COMM_ParseOnOff(device + 4, &temp))) 00396 return FALSE; 00397 00398 lpdcb->fDtrControl = temp; 00399 } 00400 else if(!strncmpiW(rtsW, device, 4)) 00401 { 00402 if(!(device = COMM_ParseOnOff(device + 4, &temp))) 00403 return FALSE; 00404 00405 lpdcb->fRtsControl = temp; 00406 } 00407 else if(!strncmpiW(idsrW, device, 5)) 00408 { 00409 if(!(device = COMM_ParseOnOff(device + 5, &temp))) 00410 return FALSE; 00411 00412 /* Win NT sets the fDsrSensitivity member based on the 00413 idsr parameter. Win 9x sets fOutxDsrFlow instead. */ 00414 lpdcb->fDsrSensitivity = temp; 00415 } 00416 else 00417 return FALSE; 00418 00419 /* After the above parsing, the next character (if not the end of 00420 the string) should be a space */ 00421 if(*device && *device != ' ') 00422 return FALSE; 00423 } 00424 00425 /* If stop bits were not specified, a default is always supplied. */ 00426 if(!stop) 00427 { 00428 if(baud && lpdcb->BaudRate == 110) 00429 lpdcb->StopBits = TWOSTOPBITS; 00430 else 00431 lpdcb->StopBits = ONESTOPBIT; 00432 } 00433 00434 return TRUE; 00435 } 00436 00437 /************************************************************************** 00438 * BuildCommDCBA (KERNEL32.@) 00439 * 00440 * Updates a device control block data structure with values from an 00441 * ascii device control string. The device control string has two forms 00442 * normal and extended, it must be exclusively in one or the other form. 00443 * 00444 * RETURNS 00445 * 00446 * True on success, false on a malformed control string. 00447 */ 00448 BOOL WINAPI BuildCommDCBA( 00449 LPCSTR device, /* [in] The ascii device control string used to update the DCB. */ 00450 LPDCB lpdcb) /* [out] The device control block to be updated. */ 00451 { 00452 return BuildCommDCBAndTimeoutsA(device,lpdcb,NULL); 00453 } 00454 00455 /************************************************************************** 00456 * BuildCommDCBAndTimeoutsA (KERNEL32.@) 00457 * 00458 * Updates a device control block data structure with values from an 00459 * ascii device control string. Taking timeout values from a timeouts 00460 * struct if desired by the control string. 00461 * 00462 * RETURNS 00463 * 00464 * True on success, false bad handles etc. 00465 */ 00466 BOOL WINAPI BuildCommDCBAndTimeoutsA( 00467 LPCSTR device, /* [in] The ascii device control string. */ 00468 LPDCB lpdcb, /* [out] The device control block to be updated. */ 00469 LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */ 00470 { 00471 BOOL ret = FALSE; 00472 UNICODE_STRING deviceW; 00473 00474 TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts); 00475 if(device) RtlCreateUnicodeStringFromAsciiz(&deviceW,device); 00476 else deviceW.Buffer = NULL; 00477 00478 if(deviceW.Buffer) ret = BuildCommDCBAndTimeoutsW(deviceW.Buffer,lpdcb,lptimeouts); 00479 00480 RtlFreeUnicodeString(&deviceW); 00481 return ret; 00482 } 00483 00484 /************************************************************************** 00485 * BuildCommDCBAndTimeoutsW (KERNEL32.@) 00486 * 00487 * Updates a device control block data structure with values from a 00488 * unicode device control string. Taking timeout values from a timeouts 00489 * struct if desired by the control string. 00490 * 00491 * RETURNS 00492 * 00493 * True on success, false bad handles etc 00494 */ 00495 BOOL WINAPI BuildCommDCBAndTimeoutsW( 00496 LPCWSTR devid, /* [in] The unicode device control string. */ 00497 LPDCB lpdcb, /* [out] The device control block to be updated. */ 00498 LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */ 00499 { 00500 DCB dcb; 00501 COMMTIMEOUTS timeouts; 00502 BOOL result; 00503 LPCWSTR ptr = devid; 00504 00505 TRACE("(%s,%p,%p)\n",debugstr_w(devid),lpdcb,lptimeouts); 00506 00507 memset(&timeouts, 0, sizeof timeouts); 00508 00509 /* Set DCBlength. (Windows NT does not do this, but 9x does) */ 00510 lpdcb->DCBlength = sizeof(DCB); 00511 00512 /* Make a copy of the original data structures to work with since if 00513 if there is an error in the device control string the originals 00514 should not be modified (except possibly DCBlength) */ 00515 dcb = *lpdcb; 00516 if(lptimeouts) timeouts = *lptimeouts; 00517 00518 ptr = COMM_ParseStart(ptr); 00519 00520 if(ptr == NULL) 00521 result = FALSE; 00522 else if(strchrW(ptr, ',')) 00523 result = COMM_BuildOldCommDCB(ptr, &dcb); 00524 else 00525 result = COMM_BuildNewCommDCB(ptr, &dcb, &timeouts); 00526 00527 if(result) 00528 { 00529 *lpdcb = dcb; 00530 if(lptimeouts) *lptimeouts = timeouts; 00531 return TRUE; 00532 } 00533 else 00534 { 00535 WARN("Invalid device control string: %s\n", debugstr_w(devid)); 00536 SetLastError(ERROR_INVALID_PARAMETER); 00537 return FALSE; 00538 } 00539 } 00540 00541 /************************************************************************** 00542 * BuildCommDCBW (KERNEL32.@) 00543 * 00544 * Updates a device control block structure with values from an 00545 * unicode device control string. The device control string has two forms 00546 * normal and extended, it must be exclusively in one or the other form. 00547 * 00548 * RETURNS 00549 * 00550 * True on success, false on a malformed control string. 00551 */ 00552 BOOL WINAPI BuildCommDCBW( 00553 LPCWSTR devid, /* [in] The unicode device control string. */ 00554 LPDCB lpdcb) /* [out] The device control block to be updated. */ 00555 { 00556 return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL); 00557 } 00558 00559 /***************************************************************************** 00560 * SetCommBreak (KERNEL32.@) 00561 * 00562 * Halts the transmission of characters to a communications device. 00563 * 00564 * PARAMS 00565 * handle [in] The communications device to suspend 00566 * 00567 * RETURNS 00568 * 00569 * True on success, and false if the communications device could not be found, 00570 * the control is not supported. 00571 * 00572 * BUGS 00573 * 00574 * Only TIOCSBRK and TIOCCBRK are supported. 00575 */ 00576 BOOL WINAPI SetCommBreak(HANDLE handle) 00577 { 00578 DWORD dwBytesReturned; 00579 return DeviceIoControl(handle, IOCTL_SERIAL_SET_BREAK_ON, NULL, 0, NULL, 0, &dwBytesReturned, NULL); 00580 } 00581 00582 /***************************************************************************** 00583 * ClearCommBreak (KERNEL32.@) 00584 * 00585 * Resumes character transmission from a communication device. 00586 * 00587 * PARAMS 00588 * 00589 * handle [in] The halted communication device whose character transmission is to be resumed 00590 * 00591 * RETURNS 00592 * 00593 * True on success and false if the communications device could not be found. 00594 * 00595 * BUGS 00596 * 00597 * Only TIOCSBRK and TIOCCBRK are supported. 00598 */ 00599 BOOL WINAPI ClearCommBreak(HANDLE handle) 00600 { 00601 DWORD dwBytesReturned; 00602 return DeviceIoControl(handle, IOCTL_SERIAL_SET_BREAK_OFF, NULL, 0, NULL, 0, &dwBytesReturned, NULL); 00603 } 00604 00605 /***************************************************************************** 00606 * EscapeCommFunction (KERNEL32.@) 00607 * 00608 * Directs a communication device to perform an extended function. 00609 * 00610 * PARAMS 00611 * 00612 * handle [in] The communication device to perform the extended function 00613 * nFunction [in] The extended function to be performed 00614 * 00615 * RETURNS 00616 * 00617 * True or requested data on successful completion of the command, 00618 * false if the device is not present cannot execute the command 00619 * or the command failed. 00620 */ 00621 BOOL WINAPI EscapeCommFunction(HANDLE handle, DWORD func) 00622 { 00623 DWORD ioc; 00624 DWORD dwBytesReturned; 00625 00626 switch (func) 00627 { 00628 case CLRDTR: ioc = IOCTL_SERIAL_CLR_DTR; break; 00629 case CLRRTS: ioc = IOCTL_SERIAL_CLR_RTS; break; 00630 case SETDTR: ioc = IOCTL_SERIAL_SET_DTR; break; 00631 case SETRTS: ioc = IOCTL_SERIAL_SET_RTS; break; 00632 case SETXOFF: ioc = IOCTL_SERIAL_SET_XOFF; break; 00633 case SETXON: ioc = IOCTL_SERIAL_SET_XON; break; 00634 case SETBREAK: ioc = IOCTL_SERIAL_SET_BREAK_ON; break; 00635 case CLRBREAK: ioc = IOCTL_SERIAL_SET_BREAK_OFF; break; 00636 case RESETDEV: ioc = IOCTL_SERIAL_RESET_DEVICE; break; 00637 default: 00638 ERR("Unknown function code (%u)\n", func); 00639 SetLastError(ERROR_INVALID_PARAMETER); 00640 return FALSE; 00641 } 00642 return DeviceIoControl(handle, ioc, NULL, 0, NULL, 0, &dwBytesReturned, NULL); 00643 } 00644 00645 /******************************************************************** 00646 * PurgeComm (KERNEL32.@) 00647 * 00648 * Terminates pending operations and/or discards buffers on a 00649 * communication resource. 00650 * 00651 * PARAMS 00652 * 00653 * handle [in] The communication resource to be purged 00654 * flags [in] Flags for clear pending/buffer on input/output 00655 * 00656 * RETURNS 00657 * 00658 * True on success and false if the communications handle is bad. 00659 */ 00660 BOOL WINAPI PurgeComm(HANDLE handle, DWORD flags) 00661 { 00662 DWORD dwBytesReturned; 00663 return DeviceIoControl(handle, IOCTL_SERIAL_PURGE, &flags, sizeof(flags), 00664 NULL, 0, &dwBytesReturned, NULL); 00665 } 00666 00667 /***************************************************************************** 00668 * ClearCommError (KERNEL32.@) 00669 * 00670 * Enables further I/O operations on a communications resource after 00671 * supplying error and current status information. 00672 * 00673 * PARAMS 00674 * 00675 * handle [in] The communication resource with the error 00676 * errors [out] Flags indicating error the resource experienced 00677 * lpStat [out] The status of the communication resource 00678 * RETURNS 00679 * 00680 * True on success, false if the communication resource handle is bad. 00681 */ 00682 BOOL WINAPI ClearCommError(HANDLE handle, LPDWORD errors, LPCOMSTAT lpStat) 00683 { 00684 SERIAL_STATUS ss; 00685 DWORD dwBytesReturned; 00686 00687 if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_COMMSTATUS, NULL, 0, 00688 &ss, sizeof(ss), &dwBytesReturned, NULL)) 00689 return FALSE; 00690 00691 if (errors) 00692 { 00693 *errors = 0; 00694 if (ss.Errors & SERIAL_ERROR_BREAK) *errors |= CE_BREAK; 00695 if (ss.Errors & SERIAL_ERROR_FRAMING) *errors |= CE_FRAME; 00696 if (ss.Errors & SERIAL_ERROR_OVERRUN) *errors |= CE_OVERRUN; 00697 if (ss.Errors & SERIAL_ERROR_QUEUEOVERRUN) *errors |= CE_RXOVER; 00698 if (ss.Errors & SERIAL_ERROR_PARITY) *errors |= CE_RXPARITY; 00699 } 00700 00701 if (lpStat) 00702 { 00703 memset(lpStat, 0, sizeof(*lpStat)); 00704 00705 if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_CTS) lpStat->fCtsHold = TRUE; 00706 if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_DSR) lpStat->fDsrHold = TRUE; 00707 if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_DCD) lpStat->fRlsdHold = TRUE; 00708 if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_XON) lpStat->fXoffHold = TRUE; 00709 if (ss.HoldReasons & SERIAL_TX_WAITING_XOFF_SENT) lpStat->fXoffSent = TRUE; 00710 if (ss.EofReceived) lpStat->fEof = TRUE; 00711 if (ss.WaitForImmediate) lpStat->fTxim = TRUE; 00712 lpStat->cbInQue = ss.AmountInInQueue; 00713 lpStat->cbOutQue = ss.AmountInOutQueue; 00714 } 00715 return TRUE; 00716 } 00717 00718 /***************************************************************************** 00719 * SetupComm (KERNEL32.@) 00720 * 00721 * Called after CreateFile to hint to the communication resource to use 00722 * specified sizes for input and output buffers rather than the default values. 00723 * 00724 * PARAMS 00725 * handle [in] The just created communication resource handle 00726 * insize [in] The suggested size of the communication resources input buffer in bytes 00727 * outsize [in] The suggested size of the communication resources output buffer in bytes 00728 * 00729 * RETURNS 00730 * 00731 * True if successful, false if the communications resource handle is bad. 00732 * 00733 * BUGS 00734 * 00735 * Stub. 00736 */ 00737 BOOL WINAPI SetupComm(HANDLE handle, DWORD insize, DWORD outsize) 00738 { 00739 SERIAL_QUEUE_SIZE sqs; 00740 DWORD dwBytesReturned; 00741 00742 sqs.InSize = insize; 00743 sqs.OutSize = outsize; 00744 return DeviceIoControl(handle, IOCTL_SERIAL_SET_QUEUE_SIZE, 00745 &sqs, sizeof(sqs), NULL, 0, &dwBytesReturned, NULL); 00746 } 00747 00748 /***************************************************************************** 00749 * GetCommMask (KERNEL32.@) 00750 * 00751 * Obtain the events associated with a communication device that will cause 00752 * a call WaitCommEvent to return. 00753 * 00754 * PARAMS 00755 * 00756 * handle [in] The communications device 00757 * evtmask [out] The events which cause WaitCommEvent to return 00758 * 00759 * RETURNS 00760 * 00761 * True on success, fail on bad device handle etc. 00762 */ 00763 BOOL WINAPI GetCommMask(HANDLE handle, LPDWORD evtmask) 00764 { 00765 DWORD dwBytesReturned; 00766 TRACE("handle %p, mask %p\n", handle, evtmask); 00767 return DeviceIoControl(handle, IOCTL_SERIAL_GET_WAIT_MASK, 00768 NULL, 0, evtmask, sizeof(*evtmask), &dwBytesReturned, NULL); 00769 } 00770 00771 /***************************************************************************** 00772 * SetCommMask (KERNEL32.@) 00773 * 00774 * There be some things we need to hear about yon there communications device. 00775 * (Set which events associated with a communication device should cause 00776 * a call WaitCommEvent to return.) 00777 * 00778 * PARAMS 00779 * 00780 * handle [in] The communications device 00781 * evtmask [in] The events that are to be monitored 00782 * 00783 * RETURNS 00784 * 00785 * True on success, false on bad handle etc. 00786 */ 00787 BOOL WINAPI SetCommMask(HANDLE handle, DWORD evtmask) 00788 { 00789 DWORD dwBytesReturned; 00790 TRACE("handle %p, mask %x\n", handle, evtmask); 00791 return DeviceIoControl(handle, IOCTL_SERIAL_SET_WAIT_MASK, 00792 &evtmask, sizeof(evtmask), NULL, 0, &dwBytesReturned, NULL); 00793 } 00794 00795 static void dump_dcb(const DCB* lpdcb) 00796 { 00797 TRACE("bytesize=%d baudrate=%d fParity=%d Parity=%d stopbits=%d\n", 00798 lpdcb->ByteSize, lpdcb->BaudRate, lpdcb->fParity, lpdcb->Parity, 00799 (lpdcb->StopBits == ONESTOPBIT) ? 1 : 00800 (lpdcb->StopBits == TWOSTOPBITS) ? 2 : 0); 00801 TRACE("%sIXON %sIXOFF\n", (lpdcb->fOutX) ? "" : "~", (lpdcb->fInX) ? "" : "~"); 00802 TRACE("fOutxCtsFlow=%d fRtsControl=%d\n", lpdcb->fOutxCtsFlow, lpdcb->fRtsControl); 00803 TRACE("fOutxDsrFlow=%d fDtrControl=%d\n", lpdcb->fOutxDsrFlow, lpdcb->fDtrControl); 00804 if (lpdcb->fOutxCtsFlow || lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE) 00805 TRACE("CRTSCTS\n"); 00806 else 00807 TRACE("~CRTSCTS\n"); 00808 } 00809 00810 /***************************************************************************** 00811 * SetCommState (KERNEL32.@) 00812 * 00813 * Re-initializes all hardware and control settings of a communications device, 00814 * with values from a device control block without affecting the input and output 00815 * queues. 00816 * 00817 * PARAMS 00818 * 00819 * handle [in] The communications device 00820 * lpdcb [out] The device control block 00821 * 00822 * RETURNS 00823 * 00824 * True on success, false on failure, e.g., if the XonChar is equal to the XoffChar. 00825 */ 00826 BOOL WINAPI SetCommState( HANDLE handle, LPDCB lpdcb) 00827 { 00828 SERIAL_BAUD_RATE sbr; 00829 SERIAL_LINE_CONTROL slc; 00830 SERIAL_HANDFLOW shf; 00831 SERIAL_CHARS sc; 00832 DWORD dwBytesReturned; 00833 00834 if (lpdcb == NULL) 00835 { 00836 SetLastError(ERROR_INVALID_PARAMETER); 00837 return FALSE; 00838 } 00839 dump_dcb(lpdcb); 00840 00841 sbr.BaudRate = lpdcb->BaudRate; 00842 00843 slc.StopBits = lpdcb->StopBits; 00844 slc.Parity = lpdcb->Parity; 00845 slc.WordLength = lpdcb->ByteSize; 00846 00847 shf.ControlHandShake = 0; 00848 shf.FlowReplace = 0; 00849 if (lpdcb->fOutxCtsFlow) shf.ControlHandShake |= SERIAL_CTS_HANDSHAKE; 00850 if (lpdcb->fOutxDsrFlow) shf.ControlHandShake |= SERIAL_DSR_HANDSHAKE; 00851 switch (lpdcb->fDtrControl) 00852 { 00853 case DTR_CONTROL_DISABLE: break; 00854 case DTR_CONTROL_ENABLE: shf.ControlHandShake |= SERIAL_DTR_CONTROL; break; 00855 case DTR_CONTROL_HANDSHAKE: shf.ControlHandShake |= SERIAL_DTR_HANDSHAKE;break; 00856 default: 00857 SetLastError(ERROR_INVALID_PARAMETER); 00858 return FALSE; 00859 } 00860 switch (lpdcb->fRtsControl) 00861 { 00862 case RTS_CONTROL_DISABLE: break; 00863 case RTS_CONTROL_ENABLE: shf.FlowReplace |= SERIAL_RTS_CONTROL; break; 00864 case RTS_CONTROL_HANDSHAKE: shf.FlowReplace |= SERIAL_RTS_HANDSHAKE; break; 00865 case RTS_CONTROL_TOGGLE: shf.FlowReplace |= SERIAL_RTS_CONTROL | 00866 SERIAL_RTS_HANDSHAKE; break; 00867 default: 00868 SetLastError(ERROR_INVALID_PARAMETER); 00869 return FALSE; 00870 } 00871 if (lpdcb->fDsrSensitivity) shf.ControlHandShake |= SERIAL_DSR_SENSITIVITY; 00872 if (lpdcb->fAbortOnError) shf.ControlHandShake |= SERIAL_ERROR_ABORT; 00873 00874 if (lpdcb->fErrorChar) shf.FlowReplace |= SERIAL_ERROR_CHAR; 00875 if (lpdcb->fNull) shf.FlowReplace |= SERIAL_NULL_STRIPPING; 00876 if (lpdcb->fTXContinueOnXoff) shf.FlowReplace |= SERIAL_XOFF_CONTINUE; 00877 if (lpdcb->fOutX) shf.FlowReplace |= SERIAL_AUTO_TRANSMIT; 00878 if (lpdcb->fInX) shf.FlowReplace |= SERIAL_AUTO_RECEIVE; 00879 00880 shf.XonLimit = lpdcb->XonLim; 00881 shf.XoffLimit = lpdcb->XoffLim; 00882 00883 sc.EofChar = lpdcb->EofChar; 00884 sc.ErrorChar = lpdcb->ErrorChar; 00885 sc.BreakChar = 0; 00886 sc.EventChar = lpdcb->EvtChar; 00887 sc.XonChar = lpdcb->XonChar; 00888 sc.XoffChar = lpdcb->XoffChar; 00889 00890 /* note: change DTR/RTS lines after setting the comm attributes, 00891 * so flow control does not interfere. 00892 */ 00893 return (DeviceIoControl(handle, IOCTL_SERIAL_SET_BAUD_RATE, 00894 &sbr, sizeof(sbr), NULL, 0, &dwBytesReturned, NULL) && 00895 DeviceIoControl(handle, IOCTL_SERIAL_SET_LINE_CONTROL, 00896 &slc, sizeof(slc), NULL, 0, &dwBytesReturned, NULL) && 00897 DeviceIoControl(handle, IOCTL_SERIAL_SET_HANDFLOW, 00898 &shf, sizeof(shf), NULL, 0, &dwBytesReturned, NULL) && 00899 DeviceIoControl(handle, IOCTL_SERIAL_SET_CHARS, 00900 &sc, sizeof(sc), NULL, 0, &dwBytesReturned, NULL)); 00901 } 00902 00903 00904 /***************************************************************************** 00905 * GetCommState (KERNEL32.@) 00906 * 00907 * Fills in a device control block with information from a communications device. 00908 * 00909 * PARAMS 00910 * handle [in] The communications device 00911 * lpdcb [out] The device control block 00912 * 00913 * RETURNS 00914 * 00915 * True on success, false if the communication device handle is bad etc 00916 * 00917 * BUGS 00918 * 00919 * XonChar and XoffChar are not set. 00920 */ 00921 BOOL WINAPI GetCommState(HANDLE handle, LPDCB lpdcb) 00922 { 00923 SERIAL_BAUD_RATE sbr; 00924 SERIAL_LINE_CONTROL slc; 00925 SERIAL_HANDFLOW shf; 00926 SERIAL_CHARS sc; 00927 DWORD dwBytesReturned; 00928 00929 TRACE("handle %p, ptr %p\n", handle, lpdcb); 00930 00931 if (!lpdcb) 00932 { 00933 SetLastError(ERROR_INVALID_PARAMETER); 00934 return FALSE; 00935 } 00936 00937 if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_BAUD_RATE, 00938 NULL, 0, &sbr, sizeof(sbr), &dwBytesReturned, NULL) || 00939 !DeviceIoControl(handle, IOCTL_SERIAL_GET_LINE_CONTROL, 00940 NULL, 0, &slc, sizeof(slc), &dwBytesReturned, NULL) || 00941 !DeviceIoControl(handle, IOCTL_SERIAL_GET_HANDFLOW, 00942 NULL, 0, &shf, sizeof(shf), &dwBytesReturned, NULL) || 00943 !DeviceIoControl(handle, IOCTL_SERIAL_GET_CHARS, 00944 NULL, 0, &sc, sizeof(sc), &dwBytesReturned, NULL)) 00945 return FALSE; 00946 00947 memset(lpdcb, 0, sizeof(*lpdcb)); 00948 lpdcb->DCBlength = sizeof(*lpdcb); 00949 00950 /* yes, they seem no never be (re)set on NT */ 00951 lpdcb->fBinary = 1; 00952 lpdcb->fParity = 0; 00953 00954 lpdcb->BaudRate = sbr.BaudRate; 00955 00956 lpdcb->StopBits = slc.StopBits; 00957 lpdcb->Parity = slc.Parity; 00958 lpdcb->ByteSize = slc.WordLength; 00959 00960 if (shf.ControlHandShake & SERIAL_CTS_HANDSHAKE) lpdcb->fOutxCtsFlow = 1; 00961 if (shf.ControlHandShake & SERIAL_DSR_HANDSHAKE) lpdcb->fOutxDsrFlow = 1; 00962 switch (shf.ControlHandShake & (SERIAL_DTR_CONTROL | SERIAL_DTR_HANDSHAKE)) 00963 { 00964 case 0: lpdcb->fDtrControl = DTR_CONTROL_DISABLE; break; 00965 case SERIAL_DTR_CONTROL: lpdcb->fDtrControl = DTR_CONTROL_ENABLE; break; 00966 case SERIAL_DTR_HANDSHAKE: lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE; break; 00967 } 00968 switch (shf.FlowReplace & (SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE)) 00969 { 00970 case 0: lpdcb->fRtsControl = RTS_CONTROL_DISABLE; break; 00971 case SERIAL_RTS_CONTROL: lpdcb->fRtsControl = RTS_CONTROL_ENABLE; break; 00972 case SERIAL_RTS_HANDSHAKE: lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE; break; 00973 case SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE: 00974 lpdcb->fRtsControl = RTS_CONTROL_TOGGLE; break; 00975 } 00976 if (shf.ControlHandShake & SERIAL_DSR_SENSITIVITY) lpdcb->fDsrSensitivity = 1; 00977 if (shf.ControlHandShake & SERIAL_ERROR_ABORT) lpdcb->fAbortOnError = 1; 00978 if (shf.FlowReplace & SERIAL_ERROR_CHAR) lpdcb->fErrorChar = 1; 00979 if (shf.FlowReplace & SERIAL_NULL_STRIPPING) lpdcb->fNull = 1; 00980 if (shf.FlowReplace & SERIAL_XOFF_CONTINUE) lpdcb->fTXContinueOnXoff = 1; 00981 lpdcb->XonLim = shf.XonLimit; 00982 lpdcb->XoffLim = shf.XoffLimit; 00983 00984 if (shf.FlowReplace & SERIAL_AUTO_TRANSMIT) lpdcb->fOutX = 1; 00985 if (shf.FlowReplace & SERIAL_AUTO_RECEIVE) lpdcb->fInX = 1; 00986 00987 lpdcb->EofChar = sc.EofChar; 00988 lpdcb->ErrorChar = sc.ErrorChar; 00989 lpdcb->EvtChar = sc.EventChar; 00990 lpdcb->XonChar = sc.XonChar; 00991 lpdcb->XoffChar = sc.XoffChar; 00992 00993 TRACE("OK\n"); 00994 dump_dcb(lpdcb); 00995 00996 return TRUE; 00997 } 00998 00999 /***************************************************************************** 01000 * TransmitCommChar (KERNEL32.@) 01001 * 01002 * Transmits a single character in front of any pending characters in the 01003 * output buffer. Usually used to send an interrupt character to a host. 01004 * 01005 * PARAMS 01006 * hComm [in] The communication device in need of a command character 01007 * chTransmit [in] The character to transmit 01008 * 01009 * RETURNS 01010 * 01011 * True if the call succeeded, false if the previous command character to the 01012 * same device has not been sent yet the handle is bad etc. 01013 * 01014 */ 01015 BOOL WINAPI TransmitCommChar(HANDLE hComm, CHAR chTransmit) 01016 { 01017 DWORD dwBytesReturned; 01018 return DeviceIoControl(hComm, IOCTL_SERIAL_IMMEDIATE_CHAR, 01019 &chTransmit, sizeof(chTransmit), NULL, 0, &dwBytesReturned, NULL); 01020 } 01021 01022 01023 /***************************************************************************** 01024 * GetCommTimeouts (KERNEL32.@) 01025 * 01026 * Obtains the request timeout values for the communications device. 01027 * 01028 * PARAMS 01029 * hComm [in] The communications device 01030 * lptimeouts [out] The struct of request timeouts 01031 * 01032 * RETURNS 01033 * 01034 * True on success, false if communications device handle is bad 01035 * or the target structure is null. 01036 */ 01037 BOOL WINAPI GetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts) 01038 { 01039 SERIAL_TIMEOUTS st; 01040 DWORD dwBytesReturned; 01041 01042 TRACE("(%p, %p)\n", hComm, lptimeouts); 01043 if (!lptimeouts) 01044 { 01045 SetLastError(ERROR_INVALID_PARAMETER); 01046 return FALSE; 01047 } 01048 if (!DeviceIoControl(hComm, IOCTL_SERIAL_GET_TIMEOUTS, 01049 NULL, 0, &st, sizeof(st), &dwBytesReturned, NULL)) 01050 return FALSE; 01051 lptimeouts->ReadIntervalTimeout = st.ReadIntervalTimeout; 01052 lptimeouts->ReadTotalTimeoutMultiplier = st.ReadTotalTimeoutMultiplier; 01053 lptimeouts->ReadTotalTimeoutConstant = st.ReadTotalTimeoutConstant; 01054 lptimeouts->WriteTotalTimeoutMultiplier = st.WriteTotalTimeoutMultiplier; 01055 lptimeouts->WriteTotalTimeoutConstant = st.WriteTotalTimeoutConstant; 01056 return TRUE; 01057 } 01058 01059 /***************************************************************************** 01060 * SetCommTimeouts (KERNEL32.@) 01061 * 01062 * Sets the timeouts used when reading and writing data to/from COMM ports. 01063 * 01064 * PARAMS 01065 * hComm [in] handle of COMM device 01066 * lptimeouts [in] pointer to COMMTIMEOUTS structure 01067 * 01068 * ReadIntervalTimeout 01069 * - converted and passes to linux kernel as c_cc[VTIME] 01070 * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant 01071 * - used in ReadFile to calculate GetOverlappedResult's timeout 01072 * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant 01073 * - used in WriteFile to calculate GetOverlappedResult's timeout 01074 * 01075 * RETURNS 01076 * 01077 * True if the timeouts were set, false otherwise. 01078 */ 01079 BOOL WINAPI SetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts) 01080 { 01081 SERIAL_TIMEOUTS st; 01082 DWORD dwBytesReturned; 01083 01084 TRACE("(%p, %p)\n", hComm, lptimeouts); 01085 01086 if (lptimeouts == NULL) 01087 { 01088 SetLastError(ERROR_INVALID_PARAMETER); 01089 return FALSE; 01090 } 01091 st.ReadIntervalTimeout = lptimeouts->ReadIntervalTimeout; 01092 st.ReadTotalTimeoutMultiplier = lptimeouts->ReadTotalTimeoutMultiplier; 01093 st.ReadTotalTimeoutConstant = lptimeouts->ReadTotalTimeoutConstant; 01094 st.WriteTotalTimeoutMultiplier = lptimeouts->WriteTotalTimeoutMultiplier; 01095 st.WriteTotalTimeoutConstant = lptimeouts->WriteTotalTimeoutConstant; 01096 01097 return DeviceIoControl(hComm, IOCTL_SERIAL_SET_TIMEOUTS, 01098 &st, sizeof(st), NULL, 0, &dwBytesReturned, NULL); 01099 } 01100 01101 /*********************************************************************** 01102 * GetCommModemStatus (KERNEL32.@) 01103 * 01104 * Obtains the four control register bits if supported by the hardware. 01105 * 01106 * PARAMS 01107 * 01108 * hFile [in] The communications device 01109 * lpModemStat [out] The control register bits 01110 * 01111 * RETURNS 01112 * 01113 * True if the communications handle was good and for hardware that 01114 * control register access, false otherwise. 01115 */ 01116 BOOL WINAPI GetCommModemStatus(HANDLE hFile, LPDWORD lpModemStat) 01117 { 01118 DWORD dwBytesReturned; 01119 return DeviceIoControl(hFile, IOCTL_SERIAL_GET_MODEMSTATUS, 01120 NULL, 0, lpModemStat, sizeof(DWORD), &dwBytesReturned, NULL); 01121 } 01122 01123 /*********************************************************************** 01124 * WaitCommEvent (KERNEL32.@) 01125 * 01126 * Wait until something interesting happens on a COMM port. 01127 * Interesting things (events) are set by calling SetCommMask before 01128 * this function is called. 01129 * 01130 * RETURNS 01131 * TRUE if successful 01132 * FALSE if failure 01133 * 01134 * The set of detected events will be written to *lpdwEventMask 01135 * ERROR_IO_PENDING will be returned the overlapped structure was passed 01136 * 01137 * BUGS: 01138 * Only supports EV_RXCHAR and EV_TXEMPTY 01139 */ 01140 BOOL WINAPI WaitCommEvent( 01141 HANDLE hFile, /* [in] handle of comm port to wait for */ 01142 LPDWORD lpdwEvents, /* [out] event(s) that were detected */ 01143 LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */ 01144 { 01145 return DeviceIoControl(hFile, IOCTL_SERIAL_WAIT_ON_MASK, NULL, 0, 01146 lpdwEvents, sizeof(DWORD), NULL, lpOverlapped); 01147 } 01148 01149 /*********************************************************************** 01150 * GetCommProperties (KERNEL32.@) 01151 * 01152 * This function fills in a structure with the capabilities of the 01153 * communications port driver. 01154 * 01155 * RETURNS 01156 * 01157 * TRUE on success, FALSE on failure 01158 * If successful, the lpCommProp structure be filled in with 01159 * properties of the comm port. 01160 */ 01161 BOOL WINAPI GetCommProperties( 01162 HANDLE hFile, /* [in] handle of the comm port */ 01163 LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */ 01164 { 01165 TRACE("(%p %p)\n",hFile,lpCommProp); 01166 if(!lpCommProp) 01167 return FALSE; 01168 01169 /* 01170 * These values should be valid for LINUX's serial driver 01171 * FIXME: Perhaps they deserve an #ifdef LINUX 01172 */ 01173 memset(lpCommProp,0,sizeof(COMMPROP)); 01174 lpCommProp->wPacketLength = 1; 01175 lpCommProp->wPacketVersion = 1; 01176 lpCommProp->dwServiceMask = SP_SERIALCOMM; 01177 lpCommProp->dwMaxTxQueue = 4096; 01178 lpCommProp->dwMaxRxQueue = 4096; 01179 lpCommProp->dwMaxBaud = BAUD_115200; 01180 lpCommProp->dwProvSubType = PST_RS232; 01181 lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS | PCF_TOTALTIMEOUTS; 01182 lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING | 01183 SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ; 01184 lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 | 01185 BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 | 01186 BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ; 01187 lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ; 01188 lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 | 01189 PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE; 01190 lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue; 01191 lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue; 01192 01193 return TRUE; 01194 } 01195 01196 /*********************************************************************** 01197 * FIXME: 01198 * The functionality of CommConfigDialogA, GetDefaultCommConfig and 01199 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL). 01200 * This is dependent on the type of COMM port, but since it is doubtful 01201 * anybody will get around to implementing support for fancy serial 01202 * ports in WINE, this is hardcoded for the time being. The name of 01203 * this DLL should be stored in and read from the system registry in 01204 * the hive HKEY_LOCAL_MACHINE, key 01205 * System\\CurrentControlSet\\Services\\Class\\Ports\\???? 01206 * where ???? is the port number... that is determined by PNP 01207 * The DLL should be loaded when the COMM port is opened, and closed 01208 * when the COMM port is closed. - MJM 20 June 2000 01209 ***********************************************************************/ 01210 static const WCHAR lpszSerialUI[] = { 01211 's','e','r','i','a','l','u','i','.','d','l','l',0 }; 01212 01213 01214 /*********************************************************************** 01215 * CommConfigDialogA (KERNEL32.@) 01216 * 01217 * Raises a dialog that allows the user to configure a comm port. 01218 * Fills the COMMCONFIG struct with information specified by the user. 01219 * This function should call a similar routine in the COMM driver... 01220 * 01221 * RETURNS 01222 * 01223 * TRUE on success, FALSE on failure 01224 * If successful, the lpCommConfig structure will contain a new 01225 * configuration for the comm port, as specified by the user. 01226 * 01227 * BUGS 01228 * The library with the CommConfigDialog code is never unloaded. 01229 * Perhaps this should be done when the comm port is closed? 01230 */ 01231 BOOL WINAPI CommConfigDialogA( 01232 LPCSTR lpszDevice, /* [in] name of communications device */ 01233 HWND hWnd, /* [in] parent window for the dialog */ 01234 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */ 01235 { 01236 LPWSTR lpDeviceW = NULL; 01237 DWORD len; 01238 BOOL r; 01239 01240 TRACE("(%s, %p, %p)\n", debugstr_a(lpszDevice), hWnd, lpCommConfig); 01241 01242 if (lpszDevice) 01243 { 01244 len = MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, NULL, 0 ); 01245 lpDeviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); 01246 MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, lpDeviceW, len ); 01247 } 01248 r = CommConfigDialogW(lpDeviceW, hWnd, lpCommConfig); 01249 HeapFree( GetProcessHeap(), 0, lpDeviceW ); 01250 return r; 01251 } 01252 01253 /*********************************************************************** 01254 * CommConfigDialogW (KERNEL32.@) 01255 * 01256 * See CommConfigDialogA. 01257 */ 01258 BOOL WINAPI CommConfigDialogW( 01259 LPCWSTR lpszDevice, /* [in] name of communications device */ 01260 HWND hWnd, /* [in] parent window for the dialog */ 01261 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */ 01262 { 01263 DWORD (WINAPI *pCommConfigDialog)(LPCWSTR, HWND, LPCOMMCONFIG); 01264 HMODULE hConfigModule; 01265 DWORD res = ERROR_INVALID_PARAMETER; 01266 01267 TRACE("(%s, %p, %p)\n", debugstr_w(lpszDevice), hWnd, lpCommConfig); 01268 hConfigModule = LoadLibraryW(lpszSerialUI); 01269 01270 if (hConfigModule) { 01271 pCommConfigDialog = (void *)GetProcAddress(hConfigModule, "drvCommConfigDialogW"); 01272 if (pCommConfigDialog) { 01273 res = pCommConfigDialog(lpszDevice, hWnd, lpCommConfig); 01274 } 01275 FreeLibrary(hConfigModule); 01276 } 01277 01278 if (res) SetLastError(res); 01279 return (res == ERROR_SUCCESS); 01280 } 01281 01282 /*********************************************************************** 01283 * GetCommConfig (KERNEL32.@) 01284 * 01285 * Fill in the COMMCONFIG structure for the comm port hFile 01286 * 01287 * RETURNS 01288 * 01289 * TRUE on success, FALSE on failure 01290 * If successful, lpCommConfig contains the comm port configuration. 01291 * 01292 * BUGS 01293 * 01294 */ 01295 BOOL WINAPI GetCommConfig( 01296 HANDLE hFile, /* [in] The communications device. */ 01297 LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */ 01298 LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure, 01299 afterwards the number of bytes copied to the buffer or 01300 the needed size of the buffer. */ 01301 { 01302 BOOL r; 01303 01304 TRACE("(%p, %p, %p) *lpdwSize: %u\n", hFile, lpCommConfig, lpdwSize, lpdwSize ? *lpdwSize : 0 ); 01305 01306 if(lpCommConfig == NULL) 01307 return FALSE; 01308 r = *lpdwSize < sizeof(COMMCONFIG); /* TRUE if not enough space */ 01309 *lpdwSize = sizeof(COMMCONFIG); 01310 if(r) 01311 return FALSE; 01312 01313 lpCommConfig->dwSize = sizeof(COMMCONFIG); 01314 lpCommConfig->wVersion = 1; 01315 lpCommConfig->wReserved = 0; 01316 r = GetCommState(hFile,&lpCommConfig->dcb); 01317 lpCommConfig->dwProviderSubType = PST_RS232; 01318 lpCommConfig->dwProviderOffset = 0; 01319 lpCommConfig->dwProviderSize = 0; 01320 01321 return r; 01322 } 01323 01324 /*********************************************************************** 01325 * SetCommConfig (KERNEL32.@) 01326 * 01327 * Sets the configuration of the communications device. 01328 * 01329 * RETURNS 01330 * 01331 * True on success, false if the handle was bad is not a communications device. 01332 */ 01333 BOOL WINAPI SetCommConfig( 01334 HANDLE hFile, /* [in] The communications device. */ 01335 LPCOMMCONFIG lpCommConfig, /* [in] The desired configuration. */ 01336 DWORD dwSize) /* [in] size of the lpCommConfig struct */ 01337 { 01338 TRACE("(%p, %p, %u)\n", hFile, lpCommConfig, dwSize); 01339 return SetCommState(hFile,&lpCommConfig->dcb); 01340 } 01341 01342 /*********************************************************************** 01343 * SetDefaultCommConfigW (KERNEL32.@) 01344 * 01345 * Initializes the default configuration for a communication device. 01346 * 01347 * PARAMS 01348 * lpszDevice [I] Name of the device targeted for configuration 01349 * lpCommConfig [I] PTR to a buffer with the configuration for the device 01350 * dwSize [I] Number of bytes in the buffer 01351 * 01352 * RETURNS 01353 * Failure: FALSE 01354 * Success: TRUE, and default configuration saved 01355 * 01356 */ 01357 BOOL WINAPI SetDefaultCommConfigW(LPCWSTR lpszDevice, LPCOMMCONFIG lpCommConfig, DWORD dwSize) 01358 { 01359 BOOL (WINAPI *lpfnSetDefaultCommConfig)(LPCWSTR, LPCOMMCONFIG, DWORD); 01360 HMODULE hConfigModule; 01361 BOOL r = FALSE; 01362 01363 TRACE("(%s, %p, %u)\n", debugstr_w(lpszDevice), lpCommConfig, dwSize); 01364 01365 hConfigModule = LoadLibraryW(lpszSerialUI); 01366 if(!hConfigModule) 01367 return r; 01368 01369 lpfnSetDefaultCommConfig = (void *)GetProcAddress(hConfigModule, "drvSetDefaultCommConfigW"); 01370 if (lpfnSetDefaultCommConfig) 01371 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize); 01372 01373 FreeLibrary(hConfigModule); 01374 01375 return r; 01376 } 01377 01378 01379 /*********************************************************************** 01380 * SetDefaultCommConfigA (KERNEL32.@) 01381 * 01382 * Initializes the default configuration for a communication device. 01383 * 01384 * See SetDefaultCommConfigW. 01385 * 01386 */ 01387 BOOL WINAPI SetDefaultCommConfigA(LPCSTR lpszDevice, LPCOMMCONFIG lpCommConfig, DWORD dwSize) 01388 { 01389 BOOL r; 01390 LPWSTR lpDeviceW = NULL; 01391 DWORD len; 01392 01393 TRACE("(%s, %p, %u)\n", debugstr_a(lpszDevice), lpCommConfig, dwSize); 01394 01395 if (lpszDevice) 01396 { 01397 len = MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, NULL, 0 ); 01398 lpDeviceW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); 01399 MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, lpDeviceW, len ); 01400 } 01401 r = SetDefaultCommConfigW(lpDeviceW,lpCommConfig,dwSize); 01402 HeapFree( GetProcessHeap(), 0, lpDeviceW ); 01403 return r; 01404 } 01405 01406 01407 /*********************************************************************** 01408 * GetDefaultCommConfigW (KERNEL32.@) 01409 * 01410 * Acquires the default configuration of the specified communication device. (unicode) 01411 * 01412 * RETURNS 01413 * 01414 * True on successful reading of the default configuration, 01415 * if the device is not found or the buffer is too small. 01416 */ 01417 BOOL WINAPI GetDefaultCommConfigW( 01418 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */ 01419 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */ 01420 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer, 01421 afterwards the number of bytes copied to the buffer or 01422 the needed size of the buffer. */ 01423 { 01424 DWORD (WINAPI *pGetDefaultCommConfig)(LPCWSTR, LPCOMMCONFIG, LPDWORD); 01425 HMODULE hConfigModule; 01426 DWORD res = ERROR_INVALID_PARAMETER; 01427 01428 TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_w(lpszName), lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 ); 01429 hConfigModule = LoadLibraryW(lpszSerialUI); 01430 01431 if (hConfigModule) { 01432 pGetDefaultCommConfig = (void *)GetProcAddress(hConfigModule, "drvGetDefaultCommConfigW"); 01433 if (pGetDefaultCommConfig) { 01434 res = pGetDefaultCommConfig(lpszName, lpCC, lpdwSize); 01435 } 01436 FreeLibrary(hConfigModule); 01437 } 01438 01439 if (res) SetLastError(res); 01440 return (res == ERROR_SUCCESS); 01441 } 01442 01443 /************************************************************************** 01444 * GetDefaultCommConfigA (KERNEL32.@) 01445 * 01446 * Acquires the default configuration of the specified communication device. (ascii) 01447 * 01448 * RETURNS 01449 * 01450 * True on successful reading of the default configuration, 01451 * if the device is not found or the buffer is too small. 01452 */ 01453 BOOL WINAPI GetDefaultCommConfigA( 01454 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */ 01455 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */ 01456 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer, 01457 afterwards the number of bytes copied to the buffer or 01458 the needed size of the buffer. */ 01459 { 01460 BOOL ret = FALSE; 01461 UNICODE_STRING lpszNameW; 01462 01463 TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_a(lpszName), lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 ); 01464 if(lpszName) RtlCreateUnicodeStringFromAsciiz(&lpszNameW,lpszName); 01465 else lpszNameW.Buffer = NULL; 01466 01467 ret = GetDefaultCommConfigW(lpszNameW.Buffer,lpCC,lpdwSize); 01468 01469 RtlFreeUnicodeString(&lpszNameW); 01470 return ret; 01471 } Generated on Sun May 27 2012 04:24:34 for ReactOS by
1.7.6.1
|