makefiles: Don't use standard libs for programs that specify -nodefaultlibs.
[wine/zf.git] / dlls / kernel32 / comm.c
blob656acb6b41f44be87c6f53b20bd37c889fa968e9
1 /*
2 * DEC 93 Erik Bos <erik@xs4all.nl>
4 * Copyright 1996 Marcus Meissner
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <stdio.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "winioctl.h"
32 #include "ddk/ntddser.h"
34 #include "wine/server.h"
35 #include "wine/unicode.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(comm);
41 /***********************************************************************
42 * COMM_Parse* (Internal)
44 * The following COMM_Parse* functions are used by the BuildCommDCB
45 * functions to help parse the various parts of the device control string.
47 static LPCWSTR COMM_ParseStart(LPCWSTR ptr)
49 static const WCHAR comW[] = {'C','O','M',0};
51 /* The device control string may optionally start with "COMx" followed
52 by an optional ':' and spaces. */
53 if(!strncmpiW(ptr, comW, 3))
55 ptr += 3;
57 /* Allow any com port above 0 as Win 9x does (NT only allows
58 values for com ports which are actually present) */
59 if(*ptr < '1' || *ptr > '9')
60 return NULL;
62 /* Advance pointer past port number */
63 while(*ptr >= '0' && *ptr <= '9') ptr++;
65 /* The com port number must be followed by a ':' or ' ' */
66 if(*ptr != ':' && *ptr != ' ')
67 return NULL;
69 /* Advance pointer to beginning of next parameter */
70 while(*ptr == ' ') ptr++;
71 if(*ptr == ':')
73 ptr++;
74 while(*ptr == ' ') ptr++;
77 /* The device control string must not start with a space. */
78 else if(*ptr == ' ')
79 return NULL;
81 return ptr;
84 static LPCWSTR COMM_ParseNumber(LPCWSTR ptr, LPDWORD lpnumber)
86 if(*ptr < '0' || *ptr > '9') return NULL;
87 *lpnumber = strtoulW(ptr, NULL, 10);
88 while(*ptr >= '0' && *ptr <= '9') ptr++;
89 return ptr;
92 static LPCWSTR COMM_ParseParity(LPCWSTR ptr, LPBYTE lpparity)
94 /* Contrary to what you might expect, Windows only sets the Parity
95 member of DCB and not fParity even when parity is specified in the
96 device control string */
98 switch(*ptr++)
100 case 'e':
101 case 'E':
102 *lpparity = EVENPARITY;
103 break;
104 case 'm':
105 case 'M':
106 *lpparity = MARKPARITY;
107 break;
108 case 'n':
109 case 'N':
110 *lpparity = NOPARITY;
111 break;
112 case 'o':
113 case 'O':
114 *lpparity = ODDPARITY;
115 break;
116 case 's':
117 case 'S':
118 *lpparity = SPACEPARITY;
119 break;
120 default:
121 return NULL;
124 return ptr;
127 static LPCWSTR COMM_ParseByteSize(LPCWSTR ptr, LPBYTE lpbytesize)
129 DWORD temp;
131 if(!(ptr = COMM_ParseNumber(ptr, &temp)))
132 return NULL;
134 if(temp >= 5 && temp <= 8)
136 *lpbytesize = temp;
137 return ptr;
139 else
140 return NULL;
143 static LPCWSTR COMM_ParseStopBits(LPCWSTR ptr, LPBYTE lpstopbits)
145 DWORD temp;
146 static const WCHAR stopbits15W[] = {'1','.','5',0};
148 if(!strncmpW(stopbits15W, ptr, 3))
150 ptr += 3;
151 *lpstopbits = ONE5STOPBITS;
153 else
155 if(!(ptr = COMM_ParseNumber(ptr, &temp)))
156 return NULL;
158 if(temp == 1)
159 *lpstopbits = ONESTOPBIT;
160 else if(temp == 2)
161 *lpstopbits = TWOSTOPBITS;
162 else
163 return NULL;
166 return ptr;
169 static LPCWSTR COMM_ParseOnOff(LPCWSTR ptr, LPDWORD lponoff)
171 static const WCHAR onW[] = {'o','n',0};
172 static const WCHAR offW[] = {'o','f','f',0};
174 if(!strncmpiW(onW, ptr, 2))
176 ptr += 2;
177 *lponoff = 1;
179 else if(!strncmpiW(offW, ptr, 3))
181 ptr += 3;
182 *lponoff = 0;
184 else
185 return NULL;
187 return ptr;
190 /***********************************************************************
191 * COMM_BuildOldCommDCB (Internal)
193 * Build a DCB using the old style settings string eg: "96,n,8,1"
195 static BOOL COMM_BuildOldCommDCB(LPCWSTR device, LPDCB lpdcb)
197 WCHAR last = 0;
199 if(!(device = COMM_ParseNumber(device, &lpdcb->BaudRate)))
200 return FALSE;
202 switch(lpdcb->BaudRate)
204 case 11:
205 case 30:
206 case 60:
207 lpdcb->BaudRate *= 10;
208 break;
209 case 12:
210 case 24:
211 case 48:
212 case 96:
213 lpdcb->BaudRate *= 100;
214 break;
215 case 19:
216 lpdcb->BaudRate = 19200;
217 break;
220 while(*device == ' ') device++;
221 if(*device++ != ',') return FALSE;
222 while(*device == ' ') device++;
224 if(!(device = COMM_ParseParity(device, &lpdcb->Parity)))
225 return FALSE;
227 while(*device == ' ') device++;
228 if(*device++ != ',') return FALSE;
229 while(*device == ' ') device++;
231 if(!(device = COMM_ParseByteSize(device, &lpdcb->ByteSize)))
232 return FALSE;
234 while(*device == ' ') device++;
235 if(*device++ != ',') return FALSE;
236 while(*device == ' ') device++;
238 if(!(device = COMM_ParseStopBits(device, &lpdcb->StopBits)))
239 return FALSE;
241 /* The last parameter for flow control is optional. */
242 while(*device == ' ') device++;
243 if(*device == ',')
245 device++;
246 while(*device == ' ') device++;
247 if(*device) last = *device++;
248 while(*device == ' ') device++;
251 /* Win NT sets the flow control members based on (or lack of) the last
252 parameter. Win 9x does not set these members. */
253 switch(last)
255 case 0:
256 lpdcb->fInX = FALSE;
257 lpdcb->fOutX = FALSE;
258 lpdcb->fOutxCtsFlow = FALSE;
259 lpdcb->fOutxDsrFlow = FALSE;
260 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
261 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
262 break;
263 case 'x':
264 case 'X':
265 lpdcb->fInX = TRUE;
266 lpdcb->fOutX = TRUE;
267 lpdcb->fOutxCtsFlow = FALSE;
268 lpdcb->fOutxDsrFlow = FALSE;
269 lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
270 lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
271 break;
272 case 'p':
273 case 'P':
274 lpdcb->fInX = FALSE;
275 lpdcb->fOutX = FALSE;
276 lpdcb->fOutxCtsFlow = TRUE;
277 lpdcb->fOutxDsrFlow = TRUE;
278 lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
279 lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
280 break;
281 default:
282 return FALSE;
285 /* This should be the end of the string. */
286 if(*device) return FALSE;
288 return TRUE;
291 /***********************************************************************
292 * COMM_BuildNewCommDCB (Internal)
294 * Build a DCB using the new style settings string.
295 * eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on"
297 static BOOL COMM_BuildNewCommDCB(LPCWSTR device, LPDCB lpdcb, LPCOMMTIMEOUTS lptimeouts)
299 DWORD temp;
300 BOOL baud = FALSE, stop = FALSE;
301 static const WCHAR baudW[] = {'b','a','u','d','=',0};
302 static const WCHAR parityW[] = {'p','a','r','i','t','y','=',0};
303 static const WCHAR dataW[] = {'d','a','t','a','=',0};
304 static const WCHAR stopW[] = {'s','t','o','p','=',0};
305 static const WCHAR toW[] = {'t','o','=',0};
306 static const WCHAR xonW[] = {'x','o','n','=',0};
307 static const WCHAR odsrW[] = {'o','d','s','r','=',0};
308 static const WCHAR octsW[] = {'o','c','t','s','=',0};
309 static const WCHAR dtrW[] = {'d','t','r','=',0};
310 static const WCHAR rtsW[] = {'r','t','s','=',0};
311 static const WCHAR idsrW[] = {'i','d','s','r','=',0};
313 while(*device)
315 while(*device == ' ') device++;
317 if(!strncmpiW(baudW, device, 5))
319 baud = TRUE;
321 if(!(device = COMM_ParseNumber(device + 5, &lpdcb->BaudRate)))
322 return FALSE;
324 else if(!strncmpiW(parityW, device, 7))
326 if(!(device = COMM_ParseParity(device + 7, &lpdcb->Parity)))
327 return FALSE;
329 else if(!strncmpiW(dataW, device, 5))
331 if(!(device = COMM_ParseByteSize(device + 5, &lpdcb->ByteSize)))
332 return FALSE;
334 else if(!strncmpiW(stopW, device, 5))
336 stop = TRUE;
338 if(!(device = COMM_ParseStopBits(device + 5, &lpdcb->StopBits)))
339 return FALSE;
341 else if(!strncmpiW(toW, device, 3))
343 if(!(device = COMM_ParseOnOff(device + 3, &temp)))
344 return FALSE;
346 lptimeouts->ReadIntervalTimeout = 0;
347 lptimeouts->ReadTotalTimeoutMultiplier = 0;
348 lptimeouts->ReadTotalTimeoutConstant = 0;
349 lptimeouts->WriteTotalTimeoutMultiplier = 0;
350 lptimeouts->WriteTotalTimeoutConstant = temp ? 60000 : 0;
352 else if(!strncmpiW(xonW, device, 4))
354 if(!(device = COMM_ParseOnOff(device + 4, &temp)))
355 return FALSE;
357 lpdcb->fOutX = temp;
358 lpdcb->fInX = temp;
360 else if(!strncmpiW(odsrW, device, 5))
362 if(!(device = COMM_ParseOnOff(device + 5, &temp)))
363 return FALSE;
365 lpdcb->fOutxDsrFlow = temp;
367 else if(!strncmpiW(octsW, device, 5))
369 if(!(device = COMM_ParseOnOff(device + 5, &temp)))
370 return FALSE;
372 lpdcb->fOutxCtsFlow = temp;
374 else if(!strncmpiW(dtrW, device, 4))
376 if(!(device = COMM_ParseOnOff(device + 4, &temp)))
377 return FALSE;
379 lpdcb->fDtrControl = temp;
381 else if(!strncmpiW(rtsW, device, 4))
383 if(!(device = COMM_ParseOnOff(device + 4, &temp)))
384 return FALSE;
386 lpdcb->fRtsControl = temp;
388 else if(!strncmpiW(idsrW, device, 5))
390 if(!(device = COMM_ParseOnOff(device + 5, &temp)))
391 return FALSE;
393 /* Win NT sets the fDsrSensitivity member based on the
394 idsr parameter. Win 9x sets fOutxDsrFlow instead. */
395 lpdcb->fDsrSensitivity = temp;
397 else
398 return FALSE;
400 /* After the above parsing, the next character (if not the end of
401 the string) should be a space */
402 if(*device && *device != ' ')
403 return FALSE;
406 /* If stop bits were not specified, a default is always supplied. */
407 if(!stop)
409 if(baud && lpdcb->BaudRate == 110)
410 lpdcb->StopBits = TWOSTOPBITS;
411 else
412 lpdcb->StopBits = ONESTOPBIT;
415 return TRUE;
418 /**************************************************************************
419 * BuildCommDCBA (KERNEL32.@)
421 * Updates a device control block data structure with values from an
422 * ascii device control string. The device control string has two forms
423 * normal and extended, it must be exclusively in one or the other form.
425 * RETURNS
427 * True on success, false on a malformed control string.
429 BOOL WINAPI BuildCommDCBA(
430 LPCSTR device, /* [in] The ascii device control string used to update the DCB. */
431 LPDCB lpdcb) /* [out] The device control block to be updated. */
433 return BuildCommDCBAndTimeoutsA(device,lpdcb,NULL);
436 /**************************************************************************
437 * BuildCommDCBAndTimeoutsA (KERNEL32.@)
439 * Updates a device control block data structure with values from an
440 * ascii device control string. Taking timeout values from a timeouts
441 * struct if desired by the control string.
443 * RETURNS
445 * True on success, false bad handles etc.
447 BOOL WINAPI BuildCommDCBAndTimeoutsA(
448 LPCSTR device, /* [in] The ascii device control string. */
449 LPDCB lpdcb, /* [out] The device control block to be updated. */
450 LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */
452 BOOL ret = FALSE;
453 UNICODE_STRING deviceW;
455 TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
456 if(device) RtlCreateUnicodeStringFromAsciiz(&deviceW,device);
457 else deviceW.Buffer = NULL;
459 if(deviceW.Buffer) ret = BuildCommDCBAndTimeoutsW(deviceW.Buffer,lpdcb,lptimeouts);
461 RtlFreeUnicodeString(&deviceW);
462 return ret;
465 /**************************************************************************
466 * BuildCommDCBAndTimeoutsW (KERNEL32.@)
468 * Updates a device control block data structure with values from a
469 * unicode device control string. Taking timeout values from a timeouts
470 * struct if desired by the control string.
472 * RETURNS
474 * True on success, false bad handles etc
476 BOOL WINAPI BuildCommDCBAndTimeoutsW(
477 LPCWSTR devid, /* [in] The unicode device control string. */
478 LPDCB lpdcb, /* [out] The device control block to be updated. */
479 LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */
481 DCB dcb;
482 COMMTIMEOUTS timeouts;
483 BOOL result;
484 LPCWSTR ptr = devid;
486 TRACE("(%s,%p,%p)\n",debugstr_w(devid),lpdcb,lptimeouts);
488 memset(&timeouts, 0, sizeof timeouts);
490 /* Set DCBlength. (Windows NT does not do this, but 9x does) */
491 lpdcb->DCBlength = sizeof(DCB);
493 /* Make a copy of the original data structures to work with since if
494 if there is an error in the device control string the originals
495 should not be modified (except possibly DCBlength) */
496 dcb = *lpdcb;
497 if(lptimeouts) timeouts = *lptimeouts;
499 ptr = COMM_ParseStart(ptr);
501 if(ptr == NULL)
502 result = FALSE;
503 else if(strchrW(ptr, ','))
504 result = COMM_BuildOldCommDCB(ptr, &dcb);
505 else
506 result = COMM_BuildNewCommDCB(ptr, &dcb, &timeouts);
508 if(result)
510 *lpdcb = dcb;
511 if(lptimeouts) *lptimeouts = timeouts;
512 return TRUE;
514 else
516 WARN("Invalid device control string: %s\n", debugstr_w(devid));
517 SetLastError(ERROR_INVALID_PARAMETER);
518 return FALSE;
522 /**************************************************************************
523 * BuildCommDCBW (KERNEL32.@)
525 * Updates a device control block structure with values from an
526 * unicode device control string. The device control string has two forms
527 * normal and extended, it must be exclusively in one or the other form.
529 * RETURNS
531 * True on success, false on a malformed control string.
533 BOOL WINAPI BuildCommDCBW(
534 LPCWSTR devid, /* [in] The unicode device control string. */
535 LPDCB lpdcb) /* [out] The device control block to be updated. */
537 return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL);
540 /***********************************************************************
541 * FIXME:
542 * The functionality of CommConfigDialogA, GetDefaultCommConfig and
543 * SetDefaultCommConfig is implemented in a DLL (usually SERIALUI.DLL).
544 * This is dependent on the type of COMM port, but since it is doubtful
545 * anybody will get around to implementing support for fancy serial
546 * ports in WINE, this is hardcoded for the time being. The name of
547 * this DLL should be stored in and read from the system registry in
548 * the hive HKEY_LOCAL_MACHINE, key
549 * System\\CurrentControlSet\\Services\\Class\\Ports\\????
550 * where ???? is the port number... that is determined by PNP
551 * The DLL should be loaded when the COMM port is opened, and closed
552 * when the COMM port is closed. - MJM 20 June 2000
553 ***********************************************************************/
554 static const WCHAR lpszSerialUI[] = {
555 's','e','r','i','a','l','u','i','.','d','l','l',0 };
558 /***********************************************************************
559 * CommConfigDialogA (KERNEL32.@)
561 * Raises a dialog that allows the user to configure a comm port.
562 * Fills the COMMCONFIG struct with information specified by the user.
563 * This function should call a similar routine in the COMM driver...
565 * RETURNS
567 * TRUE on success, FALSE on failure
568 * If successful, the lpCommConfig structure will contain a new
569 * configuration for the comm port, as specified by the user.
571 * BUGS
572 * The library with the CommConfigDialog code is never unloaded.
573 * Perhaps this should be done when the comm port is closed?
575 BOOL WINAPI CommConfigDialogA(
576 LPCSTR lpszDevice, /* [in] name of communications device */
577 HWND hWnd, /* [in] parent window for the dialog */
578 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
580 LPWSTR lpDeviceW = NULL;
581 DWORD len;
582 BOOL r;
584 TRACE("(%s, %p, %p)\n", debugstr_a(lpszDevice), hWnd, lpCommConfig);
586 if (lpszDevice)
588 len = MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, NULL, 0 );
589 lpDeviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
590 MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, lpDeviceW, len );
592 r = CommConfigDialogW(lpDeviceW, hWnd, lpCommConfig);
593 HeapFree( GetProcessHeap(), 0, lpDeviceW );
594 return r;
597 /***********************************************************************
598 * CommConfigDialogW (KERNEL32.@)
600 * See CommConfigDialogA.
602 BOOL WINAPI CommConfigDialogW(
603 LPCWSTR lpszDevice, /* [in] name of communications device */
604 HWND hWnd, /* [in] parent window for the dialog */
605 LPCOMMCONFIG lpCommConfig) /* [out] pointer to struct to fill */
607 DWORD (WINAPI *pCommConfigDialog)(LPCWSTR, HWND, LPCOMMCONFIG);
608 HMODULE hConfigModule;
609 DWORD res = ERROR_INVALID_PARAMETER;
611 TRACE("(%s, %p, %p)\n", debugstr_w(lpszDevice), hWnd, lpCommConfig);
612 hConfigModule = LoadLibraryW(lpszSerialUI);
614 if (hConfigModule) {
615 pCommConfigDialog = (void *)GetProcAddress(hConfigModule, "drvCommConfigDialogW");
616 if (pCommConfigDialog) {
617 res = pCommConfigDialog(lpszDevice, hWnd, lpCommConfig);
619 FreeLibrary(hConfigModule);
622 if (res) SetLastError(res);
623 return (res == ERROR_SUCCESS);
626 /***********************************************************************
627 * SetDefaultCommConfigW (KERNEL32.@)
629 * Initializes the default configuration for a communication device.
631 * PARAMS
632 * lpszDevice [I] Name of the device targeted for configuration
633 * lpCommConfig [I] PTR to a buffer with the configuration for the device
634 * dwSize [I] Number of bytes in the buffer
636 * RETURNS
637 * Failure: FALSE
638 * Success: TRUE, and default configuration saved
641 BOOL WINAPI SetDefaultCommConfigW(LPCWSTR lpszDevice, LPCOMMCONFIG lpCommConfig, DWORD dwSize)
643 BOOL (WINAPI *lpfnSetDefaultCommConfig)(LPCWSTR, LPCOMMCONFIG, DWORD);
644 HMODULE hConfigModule;
645 BOOL r = FALSE;
647 TRACE("(%s, %p, %u)\n", debugstr_w(lpszDevice), lpCommConfig, dwSize);
649 hConfigModule = LoadLibraryW(lpszSerialUI);
650 if(!hConfigModule)
651 return r;
653 lpfnSetDefaultCommConfig = (void *)GetProcAddress(hConfigModule, "drvSetDefaultCommConfigW");
654 if (lpfnSetDefaultCommConfig)
655 r = lpfnSetDefaultCommConfig(lpszDevice, lpCommConfig, dwSize);
657 FreeLibrary(hConfigModule);
659 return r;
663 /***********************************************************************
664 * SetDefaultCommConfigA (KERNEL32.@)
666 * Initializes the default configuration for a communication device.
668 * See SetDefaultCommConfigW.
671 BOOL WINAPI SetDefaultCommConfigA(LPCSTR lpszDevice, LPCOMMCONFIG lpCommConfig, DWORD dwSize)
673 BOOL r;
674 LPWSTR lpDeviceW = NULL;
675 DWORD len;
677 TRACE("(%s, %p, %u)\n", debugstr_a(lpszDevice), lpCommConfig, dwSize);
679 if (lpszDevice)
681 len = MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, NULL, 0 );
682 lpDeviceW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
683 MultiByteToWideChar( CP_ACP, 0, lpszDevice, -1, lpDeviceW, len );
685 r = SetDefaultCommConfigW(lpDeviceW,lpCommConfig,dwSize);
686 HeapFree( GetProcessHeap(), 0, lpDeviceW );
687 return r;
691 /***********************************************************************
692 * GetDefaultCommConfigW (KERNEL32.@)
694 * Acquires the default configuration of the specified communication device. (unicode)
696 * RETURNS
698 * True on successful reading of the default configuration,
699 * if the device is not found or the buffer is too small.
701 BOOL WINAPI GetDefaultCommConfigW(
702 LPCWSTR lpszName, /* [in] The unicode name of the device targeted for configuration. */
703 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
704 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
705 afterwards the number of bytes copied to the buffer or
706 the needed size of the buffer. */
708 DWORD (WINAPI *pGetDefaultCommConfig)(LPCWSTR, LPCOMMCONFIG, LPDWORD);
709 HMODULE hConfigModule;
710 DWORD res = ERROR_INVALID_PARAMETER;
712 TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_w(lpszName), lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 );
713 hConfigModule = LoadLibraryW(lpszSerialUI);
715 if (hConfigModule) {
716 pGetDefaultCommConfig = (void *)GetProcAddress(hConfigModule, "drvGetDefaultCommConfigW");
717 if (pGetDefaultCommConfig) {
718 res = pGetDefaultCommConfig(lpszName, lpCC, lpdwSize);
720 FreeLibrary(hConfigModule);
723 if (res) SetLastError(res);
724 return (res == ERROR_SUCCESS);
727 /**************************************************************************
728 * GetDefaultCommConfigA (KERNEL32.@)
730 * Acquires the default configuration of the specified communication device. (ascii)
732 * RETURNS
734 * True on successful reading of the default configuration,
735 * if the device is not found or the buffer is too small.
737 BOOL WINAPI GetDefaultCommConfigA(
738 LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */
739 LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */
740 LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer,
741 afterwards the number of bytes copied to the buffer or
742 the needed size of the buffer. */
744 BOOL ret = FALSE;
745 UNICODE_STRING lpszNameW;
747 TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_a(lpszName), lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 );
748 if(lpszName) RtlCreateUnicodeStringFromAsciiz(&lpszNameW,lpszName);
749 else lpszNameW.Buffer = NULL;
751 ret = GetDefaultCommConfigW(lpszNameW.Buffer,lpCC,lpdwSize);
753 RtlFreeUnicodeString(&lpszNameW);
754 return ret;