Add missing wReserved1 member to DCB structure definition.
Fix several bugs in BuildCommDCBAndTimeouts: - make sure LPCSTR parameter is really treated as constant - fix possible buffer overflow if passed in string is too long - if the device control string is invalid, do not modify DCB - do not clear entire DCB, only modify appropriate members - fix parsing of stop bits parameter so it works for 1 and 1.5 - populate COMMTIMEOUTS when to=xxx parameter is specified - added support for xon, odsr, octs, dtr, rts, and idsr parameters - fix several other parsing errors
This commit is contained in:
parent
fc7e8f5c7b
commit
8be51c92e4
|
@ -155,135 +155,350 @@ static int COMM_WhackModem(int fd, unsigned int andy, unsigned int orrie)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* COMM_Parse* (Internal)
|
||||||
|
*
|
||||||
|
* The following COMM_Parse* functions are used by the BuildCommDCB
|
||||||
|
* functions to help parse the various parts of the device control string.
|
||||||
|
*/
|
||||||
|
static LPCSTR COMM_ParseStart(LPCSTR ptr)
|
||||||
|
{
|
||||||
|
/* The device control string may optionally start with "COMx" followed
|
||||||
|
by an optional ':' and spaces. */
|
||||||
|
if(!strncasecmp(ptr, "COM", 3))
|
||||||
|
{
|
||||||
|
ptr += 3;
|
||||||
|
|
||||||
|
/* Allow any com port above 0 as Win 9x does (NT only allows
|
||||||
|
values for com ports which are actually present) */
|
||||||
|
if(*ptr < '1' || *ptr > '9')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Advance pointer past port number */
|
||||||
|
while(*ptr >= '0' && *ptr <= '9') ptr++;
|
||||||
|
|
||||||
|
/* The com port number must be followed by a ':' or ' ' */
|
||||||
|
if(*ptr != ':' && *ptr != ' ')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Advance pointer to beginning of next parameter */
|
||||||
|
while(*ptr == ' ') ptr++;
|
||||||
|
if(*ptr == ':')
|
||||||
|
{
|
||||||
|
ptr++;
|
||||||
|
while(*ptr == ' ') ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* The device control string must not start with a space. */
|
||||||
|
else if(*ptr == ' ')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPCSTR COMM_ParseNumber(LPCSTR ptr, LPDWORD lpnumber)
|
||||||
|
{
|
||||||
|
if(*ptr < '0' || *ptr > '9') return NULL;
|
||||||
|
if(!sscanf(ptr, "%ld", lpnumber)) return NULL;
|
||||||
|
while(*ptr >= '0' && *ptr <= '9') ptr++;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPCSTR COMM_ParseParity(LPCSTR ptr, LPBYTE lpparity)
|
||||||
|
{
|
||||||
|
/* Contrary to what you might expect, Windows only sets the Parity
|
||||||
|
member of DCB and not fParity even when parity is specified in the
|
||||||
|
device control string */
|
||||||
|
|
||||||
|
switch(toupper(*ptr++))
|
||||||
|
{
|
||||||
|
case 'E':
|
||||||
|
*lpparity = EVENPARITY;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
*lpparity = MARKPARITY;
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
*lpparity = NOPARITY;
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
*lpparity = ODDPARITY;
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
*lpparity = SPACEPARITY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPCSTR COMM_ParseByteSize(LPCSTR ptr, LPBYTE lpbytesize)
|
||||||
|
{
|
||||||
|
DWORD temp;
|
||||||
|
|
||||||
|
if(!(ptr = COMM_ParseNumber(ptr, &temp)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(temp >= 5 && temp <= 8)
|
||||||
|
{
|
||||||
|
*lpbytesize = temp;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPCSTR COMM_ParseStopBits(LPCSTR ptr, LPBYTE lpstopbits)
|
||||||
|
{
|
||||||
|
DWORD temp;
|
||||||
|
|
||||||
|
if(!strncmp("1.5", ptr, 3))
|
||||||
|
{
|
||||||
|
ptr += 3;
|
||||||
|
*lpstopbits = ONE5STOPBITS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!(ptr = COMM_ParseNumber(ptr, &temp)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(temp == 1)
|
||||||
|
*lpstopbits = ONESTOPBIT;
|
||||||
|
else if(temp == 2)
|
||||||
|
*lpstopbits = TWOSTOPBITS;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPCSTR COMM_ParseOnOff(LPCSTR ptr, LPDWORD lponoff)
|
||||||
|
{
|
||||||
|
if(!strncasecmp("on", ptr, 2))
|
||||||
|
{
|
||||||
|
ptr += 2;
|
||||||
|
*lponoff = 1;
|
||||||
|
}
|
||||||
|
else if(!strncasecmp("off", ptr, 3))
|
||||||
|
{
|
||||||
|
ptr += 3;
|
||||||
|
*lponoff = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* COMM_BuildOldCommDCB (Internal)
|
* COMM_BuildOldCommDCB (Internal)
|
||||||
*
|
*
|
||||||
* Build a DCB using the old style settings string eg: "COMx:96,n,8,1"
|
* Build a DCB using the old style settings string eg: "96,n,8,1"
|
||||||
* We ignore the COM port index, since we can support more than 4 ports.
|
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI COMM_BuildOldCommDCB(LPCSTR device, LPDCB lpdcb)
|
static BOOL COMM_BuildOldCommDCB(LPCSTR device, LPDCB lpdcb)
|
||||||
{
|
{
|
||||||
/* "COM1:96,n,8,1" */
|
char last = 0;
|
||||||
/* 012345 */
|
|
||||||
char *ptr, temp[256], last;
|
|
||||||
int rate;
|
|
||||||
|
|
||||||
TRACE("(%s), ptr %p\n", device, lpdcb);
|
if(!(device = COMM_ParseNumber(device, &lpdcb->BaudRate)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* Some applications call this function with "9600,n,8,1"
|
switch(lpdcb->BaudRate)
|
||||||
* not sending the "COM1:" parameter at left of string */
|
|
||||||
if (!strncasecmp(device,"COM",3))
|
|
||||||
{
|
|
||||||
if (!device[3]) return FALSE;
|
|
||||||
if (device[4] != ':' && device[4] != ' ') return FALSE;
|
|
||||||
strcpy(temp,device+5);
|
|
||||||
}
|
|
||||||
else strcpy(temp,device);
|
|
||||||
|
|
||||||
last=temp[strlen(temp)-1];
|
|
||||||
ptr = strtok(temp, ", ");
|
|
||||||
|
|
||||||
/* DOS/Windows only compares the first two numbers
|
|
||||||
* and assigns an appropriate baud rate.
|
|
||||||
* You can supply 961324245, it still returns 9600 ! */
|
|
||||||
if (strlen(ptr) < 2)
|
|
||||||
{
|
{
|
||||||
WARN("Unknown baudrate string '%s' !\n", ptr);
|
|
||||||
return FALSE; /* error: less than 2 chars */
|
|
||||||
}
|
|
||||||
ptr[2] = '\0';
|
|
||||||
rate = atoi(ptr);
|
|
||||||
|
|
||||||
switch (rate) {
|
|
||||||
case 11:
|
case 11:
|
||||||
case 30:
|
case 30:
|
||||||
case 60:
|
case 60:
|
||||||
rate *= 10;
|
lpdcb->BaudRate *= 10;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
case 24:
|
case 24:
|
||||||
case 48:
|
case 48:
|
||||||
case 96:
|
case 96:
|
||||||
rate *= 100;
|
lpdcb->BaudRate *= 100;
|
||||||
break;
|
break;
|
||||||
case 19:
|
case 19:
|
||||||
rate = 19200;
|
lpdcb->BaudRate = 19200;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(*device == ' ') device++;
|
||||||
|
if(*device++ != ',') return FALSE;
|
||||||
|
while(*device == ' ') device++;
|
||||||
|
|
||||||
|
if(!(device = COMM_ParseParity(device, &lpdcb->Parity)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
while(*device == ' ') device++;
|
||||||
|
if(*device++ != ',') return FALSE;
|
||||||
|
while(*device == ' ') device++;
|
||||||
|
|
||||||
|
if(!(device = COMM_ParseByteSize(device, &lpdcb->ByteSize)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
while(*device == ' ') device++;
|
||||||
|
if(*device++ != ',') return FALSE;
|
||||||
|
while(*device == ' ') device++;
|
||||||
|
|
||||||
|
if(!(device = COMM_ParseStopBits(device, &lpdcb->StopBits)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* The last parameter for flow control is optional. */
|
||||||
|
while(*device == ' ') device++;
|
||||||
|
if(*device == ',')
|
||||||
|
{
|
||||||
|
device++;
|
||||||
|
while(*device == ' ') device++;
|
||||||
|
if(*device) last = toupper(*device++);
|
||||||
|
while(*device == ' ') device++;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(last)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
lpdcb->fInX = FALSE;
|
||||||
|
lpdcb->fOutX = FALSE;
|
||||||
|
lpdcb->fOutxCtsFlow = FALSE;
|
||||||
|
lpdcb->fOutxDsrFlow = FALSE;
|
||||||
|
lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
|
||||||
|
lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
lpdcb->fInX = TRUE;
|
||||||
|
lpdcb->fOutX = TRUE;
|
||||||
|
lpdcb->fOutxCtsFlow = FALSE;
|
||||||
|
lpdcb->fOutxDsrFlow = FALSE;
|
||||||
|
lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
|
||||||
|
lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
lpdcb->fInX = FALSE;
|
||||||
|
lpdcb->fOutX = FALSE;
|
||||||
|
lpdcb->fOutxCtsFlow = TRUE;
|
||||||
|
lpdcb->fOutxDsrFlow = TRUE;
|
||||||
|
lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
|
||||||
|
lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN("Unknown baudrate indicator %d !\n", rate);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpdcb->BaudRate = rate;
|
/* This should be the end of the string. */
|
||||||
TRACE("baudrate (%ld)\n", lpdcb->BaudRate);
|
if(*device) return FALSE;
|
||||||
|
|
||||||
ptr = strtok(NULL, ", ");
|
return TRUE;
|
||||||
if (islower(*ptr))
|
}
|
||||||
*ptr = toupper(*ptr);
|
|
||||||
|
|
||||||
TRACE("parity (%c)\n", *ptr);
|
/***********************************************************************
|
||||||
lpdcb->fParity = TRUE;
|
* COMM_BuildNewCommDCB (Internal)
|
||||||
switch (*ptr) {
|
*
|
||||||
case 'N':
|
* Build a DCB using the new style settings string.
|
||||||
lpdcb->Parity = NOPARITY;
|
* eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on"
|
||||||
lpdcb->fParity = FALSE;
|
*/
|
||||||
break;
|
static BOOL COMM_BuildNewCommDCB(LPCSTR device, LPDCB lpdcb, LPCOMMTIMEOUTS lptimeouts)
|
||||||
case 'E':
|
{
|
||||||
lpdcb->Parity = EVENPARITY;
|
DWORD temp;
|
||||||
break;
|
BOOL baud = FALSE, stop = FALSE;
|
||||||
case 'M':
|
|
||||||
lpdcb->Parity = MARKPARITY;
|
while(*device)
|
||||||
break;
|
{
|
||||||
case 'O':
|
while(*device == ' ') device++;
|
||||||
lpdcb->Parity = ODDPARITY;
|
|
||||||
break;
|
if(!strncasecmp("baud=", device, 5))
|
||||||
case 'S':
|
{
|
||||||
lpdcb->Parity = SPACEPARITY;
|
baud = TRUE;
|
||||||
break;
|
|
||||||
default:
|
if(!(device = COMM_ParseNumber(device + 5, &lpdcb->BaudRate)))
|
||||||
WARN("Unknown parity `%c'!\n", *ptr);
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
|
else if(!strncasecmp("parity=", device, 7))
|
||||||
|
{
|
||||||
|
if(!(device = COMM_ParseParity(device + 7, &lpdcb->Parity)))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if(!strncasecmp("data=", device, 5))
|
||||||
|
{
|
||||||
|
if(!(device = COMM_ParseByteSize(device + 5, &lpdcb->ByteSize)))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if(!strncasecmp("stop=", device, 5))
|
||||||
|
{
|
||||||
|
stop = TRUE;
|
||||||
|
|
||||||
|
if(!(device = COMM_ParseStopBits(device + 5, &lpdcb->StopBits)))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if(!strncasecmp("to=", device, 3))
|
||||||
|
{
|
||||||
|
if(!(device = COMM_ParseOnOff(device + 3, &temp)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
lptimeouts->ReadIntervalTimeout = 0;
|
||||||
|
lptimeouts->ReadTotalTimeoutMultiplier = 0;
|
||||||
|
lptimeouts->ReadTotalTimeoutConstant = 0;
|
||||||
|
lptimeouts->WriteTotalTimeoutMultiplier = 0;
|
||||||
|
lptimeouts->WriteTotalTimeoutConstant = temp ? 60000 : 0;
|
||||||
|
}
|
||||||
|
else if(!strncasecmp("xon=", device, 4))
|
||||||
|
{
|
||||||
|
if(!(device = COMM_ParseOnOff(device + 4, &temp)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
lpdcb->fOutX = temp;
|
||||||
|
lpdcb->fInX = temp;
|
||||||
|
}
|
||||||
|
else if(!strncasecmp("odsr=", device, 5))
|
||||||
|
{
|
||||||
|
if(!(device = COMM_ParseOnOff(device + 5, &temp)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
lpdcb->fOutxDsrFlow = temp;
|
||||||
|
}
|
||||||
|
else if(!strncasecmp("octs=", device, 5))
|
||||||
|
{
|
||||||
|
if(!(device = COMM_ParseOnOff(device + 5, &temp)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
lpdcb->fOutxCtsFlow = temp;
|
||||||
|
}
|
||||||
|
else if(!strncasecmp("dtr=", device, 4))
|
||||||
|
{
|
||||||
|
if(!(device = COMM_ParseOnOff(device + 4, &temp)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
lpdcb->fDtrControl = temp;
|
||||||
|
}
|
||||||
|
else if(!strncasecmp("rts=", device, 4))
|
||||||
|
{
|
||||||
|
if(!(device = COMM_ParseOnOff(device + 4, &temp)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
lpdcb->fRtsControl = temp;
|
||||||
|
}
|
||||||
|
else if(!strncasecmp("idsr=", device, 5))
|
||||||
|
{
|
||||||
|
if(!(device = COMM_ParseOnOff(device + 5, &temp)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
lpdcb->fDsrSensitivity = temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* After the above parsing, the next character (if not the end of
|
||||||
|
the string) should be a space */
|
||||||
|
if(*device && *device != ' ')
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = strtok(NULL, ", ");
|
/* If stop bits were not specified, a default is always supplied. */
|
||||||
TRACE("charsize (%c)\n", *ptr);
|
if(!stop)
|
||||||
lpdcb->ByteSize = *ptr - '0';
|
{
|
||||||
|
if(baud && lpdcb->BaudRate == 110)
|
||||||
ptr = strtok(NULL, ", ");
|
lpdcb->StopBits = TWOSTOPBITS;
|
||||||
TRACE("stopbits (%c)\n", *ptr);
|
else
|
||||||
switch (*ptr) {
|
lpdcb->StopBits = ONESTOPBIT;
|
||||||
case '1':
|
|
||||||
lpdcb->StopBits = ONESTOPBIT;
|
|
||||||
break;
|
|
||||||
case '2':
|
|
||||||
lpdcb->StopBits = TWOSTOPBITS;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARN("Unknown # of stopbits `%c'!\n", *ptr);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last == 'x') {
|
|
||||||
lpdcb->fInX = TRUE;
|
|
||||||
lpdcb->fOutX = TRUE;
|
|
||||||
lpdcb->fOutxCtsFlow = FALSE;
|
|
||||||
lpdcb->fOutxDsrFlow = FALSE;
|
|
||||||
lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
|
|
||||||
lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
|
|
||||||
} else if (last=='p') {
|
|
||||||
lpdcb->fInX = FALSE;
|
|
||||||
lpdcb->fOutX = FALSE;
|
|
||||||
lpdcb->fOutxCtsFlow = TRUE;
|
|
||||||
lpdcb->fOutxDsrFlow = FALSE;
|
|
||||||
lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
|
|
||||||
lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
|
|
||||||
} else {
|
|
||||||
lpdcb->fInX = FALSE;
|
|
||||||
lpdcb->fOutX = FALSE;
|
|
||||||
lpdcb->fOutxCtsFlow = FALSE;
|
|
||||||
lpdcb->fOutxDsrFlow = FALSE;
|
|
||||||
lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
|
|
||||||
lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -321,83 +536,45 @@ BOOL WINAPI BuildCommDCBA(
|
||||||
BOOL WINAPI BuildCommDCBAndTimeoutsA(
|
BOOL WINAPI BuildCommDCBAndTimeoutsA(
|
||||||
LPCSTR device, /* [in] The ascii device control string. */
|
LPCSTR device, /* [in] The ascii device control string. */
|
||||||
LPDCB lpdcb, /* [out] The device control block to be updated. */
|
LPDCB lpdcb, /* [out] The device control block to be updated. */
|
||||||
LPCOMMTIMEOUTS lptimeouts) /* [in] The timeouts to use if asked to set them by the control string. */
|
LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */
|
||||||
{
|
{
|
||||||
int port;
|
DCB dcb;
|
||||||
char *ptr,*temp;
|
COMMTIMEOUTS timeouts;
|
||||||
|
BOOL result;
|
||||||
|
LPCSTR ptr = device;
|
||||||
|
|
||||||
TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
|
TRACE("(%s,%p,%p)\n",device,lpdcb,lptimeouts);
|
||||||
|
|
||||||
if (!strncasecmp(device,"COM",3)) {
|
/* Set DCBlength. (Windows NT does not do this, but 9x does) */
|
||||||
port=device[3]-'0';
|
lpdcb->DCBlength = sizeof(DCB);
|
||||||
if (port--==0) {
|
|
||||||
ERR("BUG! COM0 can't exist!\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if ((*(device+4)!=':') && (*(device+4)!=' '))
|
|
||||||
return FALSE;
|
|
||||||
temp=(LPSTR)(device+5);
|
|
||||||
} else
|
|
||||||
temp=(LPSTR)device;
|
|
||||||
|
|
||||||
memset(lpdcb,0,sizeof (DCB));
|
/* Make a copy of the original data structures to work with since if
|
||||||
lpdcb->DCBlength = sizeof(DCB);
|
if there is an error in the device control string the originals
|
||||||
if (strchr(temp,',')) { /* old style */
|
should not be modified (except possibly DCBlength) */
|
||||||
|
memcpy(&dcb, lpdcb, sizeof(DCB));
|
||||||
|
if(lptimeouts) memcpy(&timeouts, lptimeouts, sizeof(COMMTIMEOUTS));
|
||||||
|
|
||||||
return COMM_BuildOldCommDCB(device,lpdcb);
|
ptr = COMM_ParseStart(ptr);
|
||||||
|
|
||||||
|
if(ptr == NULL)
|
||||||
|
result = FALSE;
|
||||||
|
else if(strchr(ptr, ','))
|
||||||
|
result = COMM_BuildOldCommDCB(ptr, &dcb);
|
||||||
|
else
|
||||||
|
result = COMM_BuildNewCommDCB(ptr, &dcb, &timeouts);
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
{
|
||||||
|
memcpy(lpdcb, &dcb, sizeof(DCB));
|
||||||
|
if(lptimeouts) memcpy(lptimeouts, &timeouts, sizeof(COMMTIMEOUTS));
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
ptr=strtok(temp," ");
|
else
|
||||||
while (ptr) {
|
{
|
||||||
DWORD flag,x;
|
WARN("Invalid device control string: %s\n", device);
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
flag=0;
|
return FALSE;
|
||||||
if (!strncasecmp("baud=",ptr,5)) {
|
|
||||||
if (!sscanf(ptr+5,"%ld",&x))
|
|
||||||
WARN("Couldn't parse %s\n",ptr);
|
|
||||||
lpdcb->BaudRate = x;
|
|
||||||
flag=1;
|
|
||||||
}
|
|
||||||
if (!strncasecmp("stop=",ptr,5)) {
|
|
||||||
if (!sscanf(ptr+5,"%ld",&x))
|
|
||||||
WARN("Couldn't parse %s\n",ptr);
|
|
||||||
lpdcb->StopBits = x;
|
|
||||||
flag=1;
|
|
||||||
}
|
|
||||||
if (!strncasecmp("data=",ptr,5)) {
|
|
||||||
if (!sscanf(ptr+5,"%ld",&x))
|
|
||||||
WARN("Couldn't parse %s\n",ptr);
|
|
||||||
lpdcb->ByteSize = x;
|
|
||||||
flag=1;
|
|
||||||
}
|
|
||||||
if (!strncasecmp("parity=",ptr,7)) {
|
|
||||||
lpdcb->fParity = TRUE;
|
|
||||||
switch (ptr[7]) {
|
|
||||||
case 'N':case 'n':
|
|
||||||
lpdcb->fParity = FALSE;
|
|
||||||
lpdcb->Parity = NOPARITY;
|
|
||||||
break;
|
|
||||||
case 'E':case 'e':
|
|
||||||
lpdcb->Parity = EVENPARITY;
|
|
||||||
break;
|
|
||||||
case 'O':case 'o':
|
|
||||||
lpdcb->Parity = ODDPARITY;
|
|
||||||
break;
|
|
||||||
case 'M':case 'm':
|
|
||||||
lpdcb->Parity = MARKPARITY;
|
|
||||||
break;
|
|
||||||
case 'S':case 's':
|
|
||||||
lpdcb->Parity = SPACEPARITY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
flag=1;
|
|
||||||
}
|
|
||||||
if (!flag)
|
|
||||||
ERR("Unhandled specifier '%s', please report.\n",ptr);
|
|
||||||
ptr=strtok(NULL," ");
|
|
||||||
}
|
}
|
||||||
if (lpdcb->BaudRate==110)
|
|
||||||
lpdcb->StopBits = 2;
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -414,7 +591,7 @@ BOOL WINAPI BuildCommDCBAndTimeoutsA(
|
||||||
BOOL WINAPI BuildCommDCBAndTimeoutsW(
|
BOOL WINAPI BuildCommDCBAndTimeoutsW(
|
||||||
LPCWSTR devid, /* [in] The unicode device control string. */
|
LPCWSTR devid, /* [in] The unicode device control string. */
|
||||||
LPDCB lpdcb, /* [out] The device control block to be updated. */
|
LPDCB lpdcb, /* [out] The device control block to be updated. */
|
||||||
LPCOMMTIMEOUTS lptimeouts) /* [in] The timeouts to use if asked to set them by the control string. */
|
LPCOMMTIMEOUTS lptimeouts) /* [in] The COMMTIMEOUTS structure to be updated. */
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
LPSTR devidA;
|
LPSTR devidA;
|
||||||
|
|
|
@ -970,6 +970,7 @@ typedef struct tagDCB
|
||||||
char ErrorChar;
|
char ErrorChar;
|
||||||
char EofChar;
|
char EofChar;
|
||||||
char EvtChar;
|
char EvtChar;
|
||||||
|
WORD wReserved1;
|
||||||
} DCB, *LPDCB;
|
} DCB, *LPDCB;
|
||||||
|
|
||||||
typedef struct tagCOMMCONFIG {
|
typedef struct tagCOMMCONFIG {
|
||||||
|
|
Loading…
Reference in New Issue