[ros-diffs] [hyperion] 38362: 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

hyperion at svn.reactos.org hyperion at svn.reactos.org
Fri Dec 26 23:09:39 CET 2008


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?rev=38362&r1=38361&r2=38362&view=diff
==============================================================================
--- 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/kernel32.rbuild?rev=38362&r1=38361&r2=38362&view=diff
==============================================================================
--- 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/comm.c?rev=38362&r1=38361&r2=38362&view=diff
==============================================================================
--- 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/commdcb.c?rev=38362&view=auto
==============================================================================
--- 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



More information about the Ros-diffs mailing list