[KERNEL32]

Hey Arch, stop deleting our code!

svn path=/trunk/; revision=52749
This commit is contained in:
Timo Kreuzer 2011-07-20 20:18:17 +00:00
parent 1e3d0d1bb6
commit 1519ee0ed7
3 changed files with 675 additions and 0 deletions

View file

@ -50,6 +50,7 @@ list(APPEND SOURCE
client/misc/actctx.c
client/misc/atom.c
client/misc/comm.c
client/misc/commdcb.c
client/misc/computername.c
client/misc/dllmain.c
client/misc/env.c

View file

@ -0,0 +1,673 @@
/*
Copyright (c) 2008 KJK::Hyperion
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/* Parses a mode string for a serial port, in the same syntax as the mode.com command */
#if defined(__REACTOS__) && defined(_KERNEL32_)
#include <k32.h>
#define DCB_BuildCommDCBA BuildCommDCBA
#define DCB_BuildCommDCBAndTimeoutsA BuildCommDCBAndTimeoutsA
#define DCB_BuildCommDCBW BuildCommDCBW
#define DCB_BuildCommDCBAndTimeoutsW BuildCommDCBAndTimeoutsW
#else
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
static
void DCB_SkipSpace(const char ** ppTail)
{
while(**ppTail && isspace(**ppTail))
++ *ppTail;
}
static
size_t DCB_SkipNonSpace(const char ** ppTail)
{
const char * pOriginal = *ppTail;
while(**ppTail && !isspace(**ppTail))
++ *ppTail;
return *ppTail - pOriginal;
}
static
BOOL DCB_SetBaudRate(unsigned long baudRate, LPDCB lpDCB)
{
switch(baudRate)
{
case 11: lpDCB->BaudRate = 110; break;
case 15: lpDCB->BaudRate = 150; break;
case 30: lpDCB->BaudRate = 300; break;
case 60: lpDCB->BaudRate = 600; break;
case 12: lpDCB->BaudRate = 1200; break;
case 24: lpDCB->BaudRate = 2400; break;
case 48: lpDCB->BaudRate = 4800; break;
case 96: lpDCB->BaudRate = 9600; break;
case 19: lpDCB->BaudRate = 19200; break;
default: lpDCB->BaudRate = baudRate; break;
}
return TRUE;
}
static
BYTE DCB_SetParity(char parity, LPDCB lpDCB)
{
switch(parity)
{
case 'N':
case 'n':
lpDCB->Parity = 0;
break;
case 'O':
case 'o':
lpDCB->Parity = 1;
break;
case 'E':
case 'e':
lpDCB->Parity = 2;
break;
case 'M':
case 'm':
lpDCB->Parity = 3;
break;
case 'S':
case 's':
lpDCB->Parity = 4;
break;
default:
return FALSE;
}
return TRUE;
}
static
BYTE DCB_SetDataBits(unsigned long dataBits, LPDCB lpDCB)
{
BOOL bRet;
bRet = dataBits >= 5 && dataBits <= 8;
if(!bRet)
return bRet;
lpDCB->ByteSize = (BYTE)dataBits;
return bRet;
}
static
BOOL DCB_ParseOldSeparator(const char ** ppTail)
{
BOOL bRet;
bRet = **ppTail == 0;
if(bRet)
return bRet;
bRet = **ppTail == ',';
if(bRet)
{
++ *ppTail;
return bRet;
}
return bRet;
}
static
unsigned long DCB_ParseOldNumber(const char ** ppTail, unsigned long nDefault)
{
char * pNumTail;
unsigned long number;
DCB_SkipSpace(ppTail);
if(!isdigit(**ppTail))
return nDefault;
number = strtoul(*ppTail, &pNumTail, 10);
*ppTail = pNumTail;
DCB_SkipSpace(ppTail);
return number;
}
static
char DCB_ParseOldCharacter(const char ** ppTail, char cDefault)
{
char character;
DCB_SkipSpace(ppTail);
if(**ppTail == 0 || **ppTail == ',')
return cDefault;
character = **ppTail;
++ *ppTail;
DCB_SkipSpace(ppTail);
return character;
}
static
const char * DCB_ParseOldString(const char ** ppTail, const char * pDefault, size_t * pLength)
{
const char * string;
DCB_SkipSpace(ppTail);
if(**ppTail == 0 || **ppTail == ',')
return pDefault;
string = *ppTail;
*pLength = 0;
while(**ppTail != 0 && **ppTail != ',' && !isspace(**ppTail))
{
++ *ppTail;
++ *pLength;
}
DCB_SkipSpace(ppTail);
return string;
}
static
BOOL
DCB_ParseOldMode(const char * pTail, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts)
{
BOOL bRet;
unsigned long baudRate;
char parity;
unsigned long dataBits;
size_t stopBitsLength;
const char * stopBits;
char retry;
/* Baud rate */
baudRate = DCB_ParseOldNumber(&pTail, 0);
bRet = DCB_ParseOldSeparator(&pTail);
bRet = bRet && DCB_SetBaudRate(baudRate, lpDCB);
if(!bRet)
return bRet;
/* Parity */
parity = DCB_ParseOldCharacter(&pTail, 'E');
bRet = DCB_ParseOldSeparator(&pTail);
bRet = bRet && DCB_SetParity(parity, lpDCB);
if(!bRet)
return bRet;
/* Data bits */
dataBits = DCB_ParseOldNumber(&pTail, 7);
bRet = DCB_ParseOldSeparator(&pTail);
bRet = bRet && DCB_SetDataBits(dataBits, lpDCB);
if(!bRet)
return bRet;
/* Stop bits */
stopBitsLength = 1;
stopBits = DCB_ParseOldString(&pTail, baudRate == 110 ? "2" : "1", &stopBitsLength);
bRet = DCB_ParseOldSeparator(&pTail);
if(!bRet)
return bRet;
if(strncmp(stopBits, "1", stopBitsLength) == 0)
lpDCB->StopBits = 0;
else if(strncmp(stopBits, "1.5", stopBitsLength) == 0)
lpDCB->StopBits = 1;
else if(strncmp(stopBits, "2", stopBitsLength) == 0)
lpDCB->StopBits = 2;
else
return FALSE;
/* Retry */
retry = DCB_ParseOldCharacter(&pTail, 0);
bRet = *pTail == 0;
if(!bRet)
return bRet;
switch(retry)
{
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 'p':
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;
case 'x':
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;
default:
return FALSE;
}
return bRet;
}
static
BOOL DCB_ParseNewNumber(const char * pString, size_t cchString, unsigned long * pNumber)
{
BOOL bRet;
char * pStringEnd;
unsigned long number;
bRet = cchString > 0;
if(!bRet)
return bRet;
number = strtoul(pString, &pStringEnd, 10);
bRet = pStringEnd - pString == cchString;
if(!bRet)
return bRet;
*pNumber = number;
return bRet;
}
static
BOOL DCB_ParseNewBoolean(const char * pString, size_t cchString, BOOL * pBoolean)
{
BOOL bRet;
bRet = _strnicmp(pString, "on", cchString) == 0;
if(bRet)
{
*pBoolean = bRet;
return bRet;
}
bRet = _strnicmp(pString, "off", cchString) == 0;
if(bRet)
{
*pBoolean = !bRet;
return bRet;
}
return bRet;
}
static
BOOL
DCB_ParseNewMode(const char * pTail, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts)
{
BOOL bRet;
BOOL stopBitsSet = FALSE;
lpDCB->StopBits = 0;
while(*pTail)
{
const char * pArg;
size_t cchArg;
size_t cchArgName;
size_t cchArgValue;
const char * pArgName;
const char * pArgValue;
unsigned long nArgValue;
BOOL fArgValue;
pArg = pTail;
cchArg = DCB_SkipNonSpace(&pTail);
DCB_SkipSpace(&pTail);
for(cchArgName = 0; cchArgName < cchArg; ++ cchArgName)
{
if(pArg[cchArgName] == '=')
break;
}
bRet = cchArgName < cchArg;
if(!bRet)
return bRet;
cchArgValue = cchArg - cchArgName - 1;
pArgName = pArg;
pArgValue = pArg + cchArgName + 1;
if(_strnicmp(pArgName, "baud", cchArgName) == 0)
{
bRet = DCB_ParseNewNumber(pArgValue, cchArgValue, &nArgValue);
bRet = bRet && DCB_SetBaudRate(nArgValue, lpDCB);
if(bRet)
{
if(lpDCB->BaudRate == 110 && !stopBitsSet)
lpDCB->StopBits = 2;
else
lpDCB->StopBits = 0;
}
}
else if(_strnicmp(pArgName, "parity", cchArgName) == 0)
{
bRet = cchArgValue == 1;
bRet = bRet && DCB_SetParity(pArgValue[0], lpDCB);
}
else if(_strnicmp(pArgName, "data", cchArgName) == 0)
{
bRet = DCB_ParseNewNumber(pArgValue, cchArgValue, &nArgValue);
bRet = bRet && DCB_SetDataBits(nArgValue, lpDCB);
}
else if(_strnicmp(pArgName, "stop", cchArgName) == 0)
{
stopBitsSet = TRUE;
if(strncmp(pArgValue, "1", cchArgValue) == 0)
lpDCB->StopBits = 0;
else if(strncmp(pArgValue, "1.5", cchArgValue) == 0)
lpDCB->StopBits = 1;
else if(strncmp(pArgValue, "2", cchArgValue) == 0)
lpDCB->StopBits = 2;
else
bRet = FALSE;
}
else if(_strnicmp(pArgName, "to", cchArgName) == 0)
{
bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
if(bRet)
{
if(lpCommTimeouts)
{
memset(lpCommTimeouts, 0, sizeof(*lpCommTimeouts));
if(fArgValue)
lpCommTimeouts->WriteTotalTimeoutConstant = 60000;
}
}
}
else if(_strnicmp(pArgName, "xon", cchArgName) == 0)
{
bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
if(bRet)
{
lpDCB->fInX = !!fArgValue;
lpDCB->fOutX = !!fArgValue;
}
}
else if(_strnicmp(pArgName, "odsr", cchArgName) == 0)
{
bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
if(bRet)
lpDCB->fOutxDsrFlow = !!fArgValue;
}
else if(_strnicmp(pArgName, "octs", cchArgName) == 0)
{
bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
if(bRet)
lpDCB->fOutxCtsFlow = !!fArgValue;
}
else if(_strnicmp(pArgName, "dtr", cchArgName) == 0)
{
bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
if(bRet)
{
if(fArgValue)
lpDCB->fDtrControl = DTR_CONTROL_ENABLE;
else
lpDCB->fDtrControl = DTR_CONTROL_DISABLE;
}
else
{
bRet = _strnicmp(pArgValue, "hs", cchArgValue) == 0;
if(bRet)
lpDCB->fDtrControl = DTR_CONTROL_HANDSHAKE;
}
}
else if(_strnicmp(pArgName, "rts", cchArgName) == 0)
{
bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
if(bRet)
{
if(fArgValue)
lpDCB->fRtsControl = RTS_CONTROL_ENABLE;
else
lpDCB->fRtsControl = RTS_CONTROL_DISABLE;
}
else
{
bRet = _strnicmp(pArgValue, "hs", cchArgValue) == 0;
if(bRet)
lpDCB->fRtsControl = RTS_CONTROL_HANDSHAKE;
else
{
bRet = _strnicmp(pArgValue, "tg", cchArgValue) == 0;
if(bRet)
lpDCB->fRtsControl = RTS_CONTROL_TOGGLE;
}
}
}
else if(_strnicmp(pArgName, "idsr", cchArgName) == 0)
{
bRet = DCB_ParseNewBoolean(pArgValue, cchArgValue, &fArgValue);
if(bRet)
lpDCB->fDsrSensitivity = !!fArgValue;
}
else
bRet = FALSE;
if(!bRet)
return bRet;
}
return TRUE;
}
static
BOOL
DCB_ValidPort(unsigned long nPort)
{
BOOL bRet;
DWORD dwErr;
WCHAR szPort[3 + 10 + 1];
dwErr = GetLastError();
_snwprintf(szPort, sizeof(szPort) / sizeof(szPort[0]), L"COM%lu", nPort);
bRet = QueryDosDeviceW(szPort, NULL, 0) == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER;
if(!bRet)
dwErr = ERROR_INVALID_PARAMETER;
SetLastError(dwErr);
return bRet;
}
/*
* @implemented
*/
BOOL
WINAPI
DCB_BuildCommDCBAndTimeoutsA(LPCSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts)
{
BOOL bRet;
LPCSTR pTail = lpDef;
DCB DCBCopy;
if(_strnicmp(pTail, "COM", 3) == 0)
{
char * pNumTail;
unsigned long nPort;
pTail += 3;
if(!isdigit(*pTail))
return FALSE;
nPort = strtoul(pTail, &pNumTail, 10);
pTail = pNumTail;
bRet = DCB_ValidPort(nPort);
if(!bRet)
return bRet;
DCB_SkipSpace(&pTail);
if(*pTail == ':')
++ pTail;
DCB_SkipSpace(&pTail);
}
DCBCopy = *lpDCB;
if(isdigit(*pTail))
bRet = DCB_ParseOldMode(pTail, &DCBCopy, lpCommTimeouts);
else
bRet = DCB_ParseNewMode(pTail, &DCBCopy, lpCommTimeouts);
if(!bRet)
SetLastError(ERROR_INVALID_PARAMETER);
else
*lpDCB = DCBCopy;
return bRet;
}
/*
* @implemented
*/
BOOL
WINAPI
DCB_BuildCommDCBA(LPCSTR lpDef, LPDCB lpDCB)
{
return DCB_BuildCommDCBAndTimeoutsA(lpDef, lpDCB, NULL);
}
/*
* @implemented
*/
BOOL
WINAPI
DCB_BuildCommDCBAndTimeoutsW(LPCWSTR lpDef, LPDCB lpDCB, LPCOMMTIMEOUTS lpCommTimeouts)
{
BOOL bRet;
HANDLE hHeap;
BOOL bInvalidChars;
LPSTR pszAscii;
int cchAscii;
DWORD dwErr;
dwErr = ERROR_INVALID_PARAMETER;
cchAscii = WideCharToMultiByte(CP_ACP, 0, lpDef, -1, NULL, 0, NULL, NULL);
bRet = cchAscii > 0;
if(bRet)
{
hHeap = GetProcessHeap();
pszAscii = HeapAlloc(hHeap, 0, cchAscii);
bRet = pszAscii != NULL;
if(bRet)
{
bInvalidChars = FALSE;
cchAscii = WideCharToMultiByte(CP_ACP, 0, lpDef, -1, pszAscii, cchAscii, NULL, &bInvalidChars);
bRet = cchAscii > 0 && !bInvalidChars;
if(bRet)
bRet = DCB_BuildCommDCBAndTimeoutsA(pszAscii, lpDCB, lpCommTimeouts);
HeapFree(hHeap, 0, pszAscii);
}
else
dwErr = ERROR_OUTOFMEMORY;
}
if(!bRet)
SetLastError(dwErr);
return bRet;
}
/*
* @implemented
*/
BOOL
WINAPI
DCB_BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB)
{
return DCB_BuildCommDCBAndTimeoutsW(lpDef, lpDCB, NULL);
}
/* EOF */

View file

@ -72,6 +72,7 @@
<file>actctx.c</file>
<file>atom.c</file>
<file>comm.c</file>
<file>commdcb.c</file>
<file>computername.c</file>
<file>dllmain.c</file>
<file>env.c</file>