Author: hyperion
Date: Fri Dec 26 16:09:38 2008
New Revision: 38362
URL:
http://svn.reactos.org/svn/reactos?rev=38362&view=rev
Log:
modified dll/win32/kernel32/k32.h
modified dll/win32/kernel32/kernel32.rbuild
modified dll/win32/kernel32/misc/comm.c
added dll/win32/kernel32/misc/commdcb.c
Define _KERNEL32_ globally for kernel32, outside the common header file
Reimplemented the whole BuildCommDCB family of APIs, deleting embarrassing code by my
younger self, written almost 6 years ago. Passes the full Wine test suite, too
Added:
trunk/reactos/dll/win32/kernel32/misc/commdcb.c (with props)
Modified:
trunk/reactos/dll/win32/kernel32/k32.h
trunk/reactos/dll/win32/kernel32/kernel32.rbuild
trunk/reactos/dll/win32/kernel32/misc/comm.c
Modified: trunk/reactos/dll/win32/kernel32/k32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/k32.h?r…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/k32.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/k32.h [iso-8859-1] Fri Dec 26 16:09:38 2008
@@ -13,7 +13,6 @@
/* PSDK/NDK Headers */
#define WIN32_NO_STATUS
-#define _KERNEL32_
#include <windows.h>
#include <tlhelp32.h>
Modified: trunk/reactos/dll/win32/kernel32/kernel32.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/kernel3…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/kernel32.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/kernel32.rbuild [iso-8859-1] Fri Dec 26 16:09:38
2008
@@ -5,6 +5,7 @@
<include base="kernel32_base">.</include>
<include base="kernel32_base">include</include>
<include base="ReactOS">include/reactos/subsys</include>
+ <define name="_KERNEL32_" />
<define name="_DISABLE_TIDENTS" />
<define name="_WIN32_WINNT">0x0600</define>
<define name="__NO_CTYPE_INLINES" />
@@ -64,6 +65,7 @@
<file>collation.c</file>
<file>casemap.c</file>
<file>comm.c</file>
+ <file>commdcb.c</file>
<file>computername.c</file>
<file>console.c</file>
<file>dllmain.c</file>
Modified: trunk/reactos/dll/win32/kernel32/misc/comm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/co…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/misc/comm.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/misc/comm.c [iso-8859-1] Fri Dec 26 16:09:38 2008
@@ -17,6 +17,7 @@
* ST (05/04/2005) implemented CommConfigDialog
* DP (11/06/2005) implemented GetCommConfig
* DP (12/06/2005) implemented SetCommConfig
+ * KJK (26/12/2008) reimplemented BuildCommDCB &
BuildCommDCBAndTimeouts elsewhere
*
*/
@@ -44,735 +45,8 @@
#define NDEBUG
#include <debug.h>
-/* BUILDCOMMDCB & BUILDCOMMDCBANDTIMEOUTS */
-
-/* STRINGS */
-static const WCHAR lpszSerialUI[] = {
+static const WCHAR lpszSerialUI[] = {
's','e','r','i','a','l','u','i','.','d','l','l',0
};
-
-/* TYPES */
-
-/* Pointer to a callback that handles a particular parameter */
-typedef BOOL (*COMMDCB_PARAM_CALLBACK)(DCB *, COMMTIMEOUTS *, BOOL *, LPWSTR *);
-
-/* Symbolic flag of any length */
-typedef struct _COMMDCB_PARAM_STRFLAG
-{
- UNICODE_STRING String;
- ULONG_PTR Value;
-} COMMDCB_PARAM_STRFLAG, *PCOMMDCB_PARAM_STRFLAG;
-
-/* One char long symbolic flag */
-typedef struct _COMMDCB_PARAM_CHARFLAG
-{
- WCHAR Char;
- ULONG_PTR Value;
-} COMMDCB_PARAM_CHARFLAG, *PCOMMDCB_PARAM_CHARFLAG;
-
-/* MACROS */
-
-/* Declare a parameter handler */
-#define COMMDCB_PARAM_HANDLER(__P__) \
- BOOL COMMDCB_ ## __P__ ## Param \
- ( \
- DCB * Dcb, \
- COMMTIMEOUTS * Timeouts, \
- BOOL *StopBitsSet, \
- LPWSTR *StrTail \
- )
-
-/* UTILITIES */
-/*
- Lookup a string flag and return its numerical value. The flags array must be
- sorted - a dichotomycal search is performed
-*/
-static BOOL
-COMMDCB_LookupStrFlag(PUNICODE_STRING Flag,
- PCOMMDCB_PARAM_STRFLAG Flags,
- int FlagCount,
- PULONG_PTR Value)
-{
- /* Lower and upper bound for dichotomycal search */
- int nLowerBound = 0;
- int nUpperBound = FlagCount - 1;
-
- do
- {
- LONG nComparison;
- /* pick the element in the middle of the area of interest as the pivot */
- int nCurFlag = nLowerBound + (nUpperBound - nLowerBound) / 2;
-
- /* compare the string with the pivot */
- nComparison = RtlCompareUnicodeString(Flag,
- &Flags[nCurFlag].String,
- TRUE);
-
- /* string is equal */
- if(nComparison == 0)
- {
- /* return the flag's value */
- *Value = Flags[nCurFlag].Value;
-
- /* success */
- return TRUE;
- }
- else if(nComparison < 0)
- {
- /*
- * restrict the search to the first half of the current slice, minus the
pivot
- */
- nUpperBound = nCurFlag - 1;
- }
- else
- {
- /*
- * restrict the search to the second half of the current slice, minus the
pivot
- */
- nLowerBound = nCurFlag + 1;
- }
- } while(nLowerBound <= nUpperBound);
-
- /* string not found: failure */
- return FALSE;
-}
-
-/* PARSERS */
-/*
- Find the next character flag and return its numerical value. The flags array
- must be sorted - a dichotomycal search is performed
-*/
-static BOOL
-COMMDCB_ParseCharFlag(LPWSTR *StrTail,
- PCOMMDCB_PARAM_CHARFLAG Flags,
- int FlagCount,
- PULONG_PTR Value)
-{
- /* Lower and upper bound for dichotomycal search */
- int nLowerBound = 0;
- int nUpperBound = FlagCount - 1;
- /* get the first character as the flag */
- WCHAR wcFlag = (*StrTail)[0];
-
- /* premature end of string, or the character is whitespace */
- if(!wcFlag || iswspace(wcFlag))
- return FALSE;
-
- /* uppercase the character for case-insensitive search */
- wcFlag = towupper(wcFlag);
-
- /* skip the character flag */
- (*StrTail)++;
-
- /* see COMMDCB_LookupStrFlag for a description of the algorithm */
- do
- {
- LONG nComparison;
- int nCurFlag = nLowerBound + (nUpperBound - nLowerBound) / 2;
-
- nComparison = wcFlag - towupper(Flags[nCurFlag].Char);
-
- if(nComparison == 0)
- {
- *Value = Flags[nCurFlag].Value;
-
- return TRUE;
- }
- else if(nComparison < 0)
- {
- nUpperBound = nCurFlag - 1;
- }
- else
- {
- nLowerBound = nCurFlag + 1;
- }
- } while(nUpperBound >= nLowerBound);
-
- /* flag not found: failure */
- return FALSE;
-}
-
-/*
- Find the next string flag and return its numerical value. The flags array must
- be sorted - a dichotomycal search is performed
-*/
-static BOOL
-COMMDCB_ParseStrFlag(LPWSTR *StrTail,
- PCOMMDCB_PARAM_STRFLAG Flags,
- int FlagCount,
- PULONG_PTR Value)
-{
- LPWSTR pwcNewTail;
- UNICODE_STRING wstrFlag;
-
- /* scan the string until the first space character or the terminating null */
- for(pwcNewTail = *StrTail;
- pwcNewTail[0] && !iswspace(pwcNewTail[0]);
- pwcNewTail++);
-
- /* string flag empty */
- if(pwcNewTail == *StrTail)
- return FALSE;
-
- /* build the UNICODE_STRING description of the string flag */
- wstrFlag.Buffer = *StrTail;
- wstrFlag.Length = (pwcNewTail - *StrTail) * sizeof(WCHAR);
- wstrFlag.MaximumLength = wstrFlag.Length;
-
- /* skip the string flag */
- *StrTail = pwcNewTail;
-
- /* lookup the string flag's value and return it */
- return COMMDCB_LookupStrFlag(&wstrFlag, Flags, FlagCount, Value);
-}
-
-/*
- Parse a boolean value in the symbolic form on/off
-*/
-static BOOL
-COMMDCB_ParseBool(LPWSTR *StrTail,
- PBOOL Value)
-{
- BOOL bRetVal;
- ULONG_PTR nValue;
- static COMMDCB_PARAM_STRFLAG a_BoolFlags[] = {
- { RTL_CONSTANT_STRING(L"off"), FALSE },
- { RTL_CONSTANT_STRING(L"on"), TRUE }
- };
-
- /* try to recognize the next flag as a boolean */
- bRetVal = COMMDCB_ParseStrFlag(StrTail,
- a_BoolFlags,
- sizeof(a_BoolFlags) / sizeof(a_BoolFlags[0]),
- &nValue);
-
-
- if(!bRetVal)
- return FALSE;
-
- /* success */
- *Value = (nValue ? TRUE : FALSE);
- return TRUE;
-}
-
-/*
- Parse a decimal integer
-*/
-static BOOL
-COMMDCB_ParseInt(LPWSTR *StrTail,
- DWORD *Value)
-{
- LPWSTR pwcPrevTail = *StrTail;
- DWORD nValue = wcstoul(*StrTail, StrTail, 10);
-
- /* no character was consumed: failure */
- if(pwcPrevTail == *StrTail)
- return FALSE;
-
- /* success */
- *Value = nValue;
- return TRUE;
-}
-
-/* PARAMETER HANDLERS */
-/* baud= */
-COMMDCB_PARAM_HANDLER(baud)
-{
- DWORD nValue;
-
- (void)Timeouts;
-
- /* parse the baudrate */
- if(!COMMDCB_ParseInt(StrTail, &nValue))
- return FALSE;
-
- switch(nValue)
- {
- /* documented abbreviations */
- case 11:
- Dcb->BaudRate = 110;
- break;
- case 15:
- Dcb->BaudRate = 150;
- break;
- case 30:
- Dcb->BaudRate = 300;
- break;
- case 60:
- Dcb->BaudRate = 600;
- break;
- case 12:
- Dcb->BaudRate = 1200;
- break;
- case 24:
- Dcb->BaudRate = 2400;
- break;
- case 48:
- Dcb->BaudRate = 4800;
- break;
- case 96:
- Dcb->BaudRate = 9600;
- break;
- case 19:
- Dcb->BaudRate = 19200;
- break;
-
- /* literal value */
- default:
- Dcb->BaudRate = nValue;
- break;
- }
-
- /* if the stop bits haven't been specified explicitely */
- if(!(*StopBitsSet))
- {
- /* default the stop bits to 2 for 110 baud */
- if(Dcb->BaudRate == 110)
- Dcb->StopBits = TWOSTOPBITS;
- /* else, default the stop bits to 1 */
- else
- Dcb->StopBits = ONESTOPBIT;
- }
-
- /* success */
- return TRUE;
-}
-
-/* data= */
-COMMDCB_PARAM_HANDLER(data)
-{
- DWORD nValue;
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the data bits */
- if(!COMMDCB_ParseInt(StrTail, &nValue))
- return FALSE;
-
- /* value out of range: failure */
- if(nValue < 5 || nValue > 8)
- return FALSE;
-
- /* success */
- Dcb->ByteSize = (BYTE)nValue;
- return TRUE;
-}
-
-/* dtr= */
-COMMDCB_PARAM_HANDLER(dtr)
-{
- BOOL bRetVal;
- ULONG_PTR nValue;
- static COMMDCB_PARAM_STRFLAG a_DTRFlags[] = {
- { RTL_CONSTANT_STRING(L"hs"), DTR_CONTROL_HANDSHAKE },
- { RTL_CONSTANT_STRING(L"off"), DTR_CONTROL_DISABLE },
- { RTL_CONSTANT_STRING(L"on"), DTR_CONTROL_ENABLE }
- };
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- bRetVal = COMMDCB_ParseStrFlag(StrTail,
- a_DTRFlags,
- sizeof(a_DTRFlags) / sizeof(a_DTRFlags[0]),
- &nValue);
-
- /* failure */
- if(!bRetVal)
- return FALSE;
-
- /* success */
- Dcb->fDtrControl = nValue;
- return TRUE;
-}
-
-/* idsr= */
-COMMDCB_PARAM_HANDLER(idsr)
-{
- BOOL bValue;
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- if(!COMMDCB_ParseBool(StrTail, &bValue))
- return FALSE;
-
- /* success */
- Dcb->fDsrSensitivity = bValue;
- return TRUE;
-}
-
-/* octs= */
-COMMDCB_PARAM_HANDLER(octs)
-{
- BOOL bValue;
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- if(!COMMDCB_ParseBool(StrTail, &bValue))
- return FALSE;
-
- /* success */
- Dcb->fOutxCtsFlow = bValue;
- return TRUE;
-}
-
-/* odsr= */
-COMMDCB_PARAM_HANDLER(odsr)
-{
- BOOL bValue;
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- if(!COMMDCB_ParseBool(StrTail, &bValue))
- return FALSE;
-
- /* success */
- Dcb->fOutxDsrFlow = bValue;
- return TRUE;
-}
-
-/* parity= */
-COMMDCB_PARAM_HANDLER(parity)
-{
- BOOL bRetVal;
- ULONG_PTR nValue;
- static COMMDCB_PARAM_CHARFLAG a_ParityFlags[] = {
- { L'e', EVENPARITY },
- { L'm', MARKPARITY },
- { L'n', NOPARITY },
- { L'o', ODDPARITY },
- { L's', SPACEPARITY }
- };
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- bRetVal = COMMDCB_ParseCharFlag(StrTail,
- a_ParityFlags,
- sizeof(a_ParityFlags) / sizeof(a_ParityFlags[0]),
- &nValue);
-
- /* failure */
- if(!bRetVal)
- return FALSE;
-
- /* success */
- Dcb->Parity = (BYTE)nValue;
- return TRUE;
-}
-
-/* rts= */
-COMMDCB_PARAM_HANDLER(rts)
-{
- DWORD nRetVal;
- ULONG_PTR nValue;
- static COMMDCB_PARAM_STRFLAG a_RTSFlags[] = {
- { RTL_CONSTANT_STRING(L"hs"), RTS_CONTROL_HANDSHAKE },
- { RTL_CONSTANT_STRING(L"off"), RTS_CONTROL_DISABLE },
- { RTL_CONSTANT_STRING(L"on"), RTS_CONTROL_ENABLE },
- { RTL_CONSTANT_STRING(L"tg"), RTS_CONTROL_TOGGLE }
- };
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- nRetVal = COMMDCB_ParseStrFlag(StrTail,
- a_RTSFlags,
- sizeof(a_RTSFlags) / sizeof(a_RTSFlags[0]),
- &nValue);
-
- /* failure */
- if(!nRetVal)
- return FALSE;
-
- /* success */
- Dcb->fRtsControl = nValue;
- return TRUE;
-}
-
-/* stop= */
-COMMDCB_PARAM_HANDLER(stop)
-{
- BOOL bRetVal;
- ULONG_PTR nValue;
- static COMMDCB_PARAM_STRFLAG a_StopFlags[] = {
- { RTL_CONSTANT_STRING(L"1"), ONESTOPBIT },
- { RTL_CONSTANT_STRING(L"1.5"), ONE5STOPBITS },
- { RTL_CONSTANT_STRING(L"2"), TWOSTOPBITS }
- };
-
- (void)Timeouts;
-
- /* parse the flag */
- bRetVal = COMMDCB_ParseStrFlag(StrTail,
- a_StopFlags,
- sizeof(a_StopFlags) / sizeof(a_StopFlags[0]),
- &nValue);
-
- /* failure */
- if(!bRetVal)
- return FALSE;
-
- /* tell the baud= handler that the stop bits have been specified explicitely */
- *StopBitsSet = TRUE;
-
- /* success */
- Dcb->StopBits = (BYTE)nValue;
- return TRUE;
-}
-
-/* to= */
-COMMDCB_PARAM_HANDLER(to)
-{
- BOOL bValue;
-
- (void)Dcb;
- (void)StopBitsSet;
-
- /* parse the flag */
- if(!COMMDCB_ParseBool(StrTail, &bValue))
- return FALSE;
-
- /* for BuildCommDCB(), Timeouts is NULL */
- if(Timeouts)
- {
- /* why? no idea. All values taken from Windows 2000 with experimentation */
- Timeouts->ReadIntervalTimeout = 0;
- Timeouts->ReadTotalTimeoutMultiplier = 0;
- Timeouts->ReadTotalTimeoutConstant = 0;
- Timeouts->WriteTotalTimeoutMultiplier = 0;
-
- if(bValue)
- {
- /* timeout */
- Timeouts->WriteTotalTimeoutConstant = 60000;
- }
- else
- {
- /* no timeout */
- Timeouts->WriteTotalTimeoutConstant = 0;
- }
- }
-
- /* success */
- return TRUE;
-}
-
-/* xon= */
-COMMDCB_PARAM_HANDLER(xon)
-{
- BOOL bValue;
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- if(!COMMDCB_ParseBool(StrTail, &bValue))
- return FALSE;
-
- if(bValue)
- {
- /* XON/XOFF */
- Dcb->fInX = Dcb->fOutX = TRUE;
- }
- else
- {
- /* no XON/XOFF */
- Dcb->fInX = Dcb->fOutX = FALSE;
- }
-
- /* success */
- return TRUE;
-}
-
-/* FUNCTIONS */
-#define COMMDCB_PARAM(__P__) \
- { \
- RTL_CONSTANT_STRING(L""UNICODIZE(#__P__ )), \
- (ULONG_PTR)&COMMDCB_ ## __P__ ## Param \
- }
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-BuildCommDCBAndTimeoutsW(LPCWSTR lpDef,
- LPDCB lpDCB,
- LPCOMMTIMEOUTS lpCommTimeouts)
-{
- /* tell the baud= handler that the stop bits should be defaulted */
- BOOL bStopBitsSet = FALSE;
-
- /* parameter validation */
- if(lpDCB->DCBlength != sizeof(DCB))
- goto InvalidParam;
-
- /* set defaults */
- lpDCB->StopBits = ONESTOPBIT;
-
- /*
- * The documentation for MODE says that data= defaults to 7, but BuildCommDCB
- * doesn't seem to set it
- */
- /* lpDCB->ByteSize = 7; */
-
- /* skip COMx[n] */
- if(lpDef[0] &&
- towupper(lpDef[0]) == L'C' &&
- lpDef[1] &&
- towupper(lpDef[1]) == L'O' &&
- lpDef[2] &&
- towupper(lpDef[2]) == L'M')
- {
- DWORD nDummy;
-
- /* skip "COM" */
- lpDef += 3;
-
- /* premature end of string */
- if(!lpDef[0])
- goto InvalidParam;
-
- /* skip "x" */
- if(!COMMDCB_ParseInt((LPWSTR *)&lpDef, &nDummy))
- goto InvalidParam;
-
- /* skip ":" */
- if(lpDef[0] == L':')
- lpDef++;
- }
-
- /* skip leading whitespace */
- while(lpDef[0] && iswspace(lpDef[0]))
- lpDef++;
-
- /* repeat until the end of the string */
- while(lpDef[0])
- {
- static COMMDCB_PARAM_STRFLAG a_Params[] = {
- COMMDCB_PARAM(baud),
- COMMDCB_PARAM(data),
- COMMDCB_PARAM(dtr),
- COMMDCB_PARAM(idsr),
- COMMDCB_PARAM(octs),
- COMMDCB_PARAM(odsr),
- COMMDCB_PARAM(parity),
- COMMDCB_PARAM(rts),
- COMMDCB_PARAM(stop),
- COMMDCB_PARAM(to),
- COMMDCB_PARAM(xon)
- };
- BOOL bRetVal;
- COMMDCB_PARAM_CALLBACK pCallback;
- UNICODE_STRING wstrParam;
- LPWSTR pwcPrevTail = (LPWSTR)lpDef;
-
- /* get the parameter */
- while(lpDef[0] && lpDef[0] != L'=')
- lpDef++;
-
- /* premature end of string */
- if(!lpDef[0])
- goto InvalidParam;
-
- /* build the parameter's UNICODE_STRING */
- wstrParam.Buffer = pwcPrevTail;
- wstrParam.Length = (lpDef - pwcPrevTail) * sizeof(WCHAR);
- wstrParam.MaximumLength = wstrParam.Length;
-
- /* skip the "=" */
- lpDef++;
-
- /* lookup the callback for the parameter */
- bRetVal = COMMDCB_LookupStrFlag(&wstrParam,
- a_Params,
- sizeof(a_Params) / sizeof(a_Params[0]),
- (ULONG_PTR *)&pCallback);
-
- /* invalid parameter */
- if(!bRetVal)
- goto InvalidParam;
-
- /* call the callback to parse the parameter's argument */
- if(!pCallback(lpDCB, lpCommTimeouts, &bStopBitsSet, (LPWSTR *)&lpDef))
- goto InvalidParam;
-
- /* skip trailing whitespace */
- while(lpDef[0] && iswspace(lpDef[0]))
- lpDef++;
- }
-
- /* success */
- return TRUE;
-
-InvalidParam:
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-BuildCommDCBAndTimeoutsA(LPCSTR lpDef,
- LPDCB lpDCB,
- LPCOMMTIMEOUTS lpCommTimeouts)
-{
- NTSTATUS Status;
- BOOL bRetVal;
- ANSI_STRING strDef;
- UNICODE_STRING wstrDef;
-
- RtlInitAnsiString(&strDef, (LPSTR)lpDef);
-
- Status = RtlAnsiStringToUnicodeString(&wstrDef, &strDef, TRUE);
-
- if(!NT_SUCCESS(Status))
- {
- SetLastErrorByStatus(Status);
- return FALSE;
- }
-
- bRetVal = BuildCommDCBAndTimeoutsW(wstrDef.Buffer, lpDCB, lpCommTimeouts);
-
- RtlFreeUnicodeString(&wstrDef);
-
- return bRetVal;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-BuildCommDCBA(LPCSTR lpDef, LPDCB lpDCB)
-{
- return BuildCommDCBAndTimeoutsA(lpDef, lpDCB, NULL);
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB)
-{
- return BuildCommDCBAndTimeoutsW(lpDef, lpDCB, NULL);
-}
-
/*
* @implemented
@@ -905,7 +179,7 @@
result = drvCommDlgW(lpszName, hWnd, lpCC);
SetLastError(result);
FreeLibrary(hSerialuiDll);
-
+
return (result == ERROR_SUCCESS ? TRUE : FALSE);
}
@@ -976,7 +250,7 @@
return FALSE;
}
- if( (NULL == lpdwSize)
+ if( (NULL == lpdwSize)
|| (NULL == lpCC) ) {
DPRINT("GetCommConfig() - invalid parameter\n");
SetLastError(ERROR_INVALID_PARAMETER);
Added: trunk/reactos/dll/win32/kernel32/misc/commdcb.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/co…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/misc/commdcb.c (added)
+++ trunk/reactos/dll/win32/kernel32/misc/commdcb.c [iso-8859-1] Fri Dec 26 16:09:38 2008
@@ -1,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(20127, 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(20127, 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 */
Propchange: trunk/reactos/dll/win32/kernel32/misc/commdcb.c
------------------------------------------------------------------------------
svn:eol-style = native