/*
 * This DLL contains the user interface for the serial driver.
 *    a dialog box to configure the specified COMM port
 *    an interface to the control panel (??)
 *    functions to load and save default configuration
 *
 * Eventually the 32 bit comm port driver could be moved into here
 * and interfaced to KERNEL32 using the WIN95 or WINNT comm driver interface.
 * This way, different driver DLLS could be written to support other
 * serial interfaces, such as X.25, etc.
 *
 * Basic structure copied from COMCTL32 code.
 *
 * Copyright 2000, 2004 Mike McCormack
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"
#include "wine/unicode.h"

#include <string.h>
#include <stdarg.h>
#include <stdio.h>

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/debug.h"
#include "serialui.h"
#include "winerror.h"

WINE_DEFAULT_DEBUG_CHANNEL(comm);

static HMODULE SERIALUI_hModule;

static const WCHAR comW[] = {'c','o','m',0 };

/***********************************************************************
 * DllMain [Internal] Initializes the internal 'SERIALUI.DLL'.
 *
 * PARAMS
 *     hinstDLL    [I] handle to the DLL's instance
 *     fdwReason   [I]
 *     lpvReserved [I] reserved, must be NULL
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */

BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);

    switch (fdwReason) {
	case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls(hinstDLL);
            SERIALUI_hModule = hinstDLL;
	    break;
	case DLL_PROCESS_DETACH:
	    break;
    }

    return TRUE;
}


/***********************************************************************
 * EnumPropPages (SERIALUI.2)
 *
 * Called by the device manager to add prop sheets in Control Panel ???
 * Pointed to in Win98 registry by
 * \System\CurrentControlSet\Services\Class\ports\0000\EnumPropPages =
 *  "serialui.dll,EnumPropPages"
 */
typedef LPVOID LPDEVICE_INFO;
typedef LPVOID LPFNADDPROPSHEETPAGE;
BOOL WINAPI EnumPropPages(LPDEVICE_INFO pdi, LPFNADDPROPSHEETPAGE pfnAdd, LPARAM lParam )
{
    FIXME("(%p %p %lx)\n",pdi,pfnAdd,lParam);
    return FALSE;
}

/*
 * These data structures are convert from values used in fields of a DCB
 * to strings used in the CommConfigDialog.
 */
typedef struct tagPARAM2STRDATA
{
    DWORD        val;
    CONST CHAR  *name;
} PARAM2STRDATA, *LPPARAM2STRDATA;

typedef struct tagPARAM2STR
{
    DWORD         dwSize;
    LPPARAM2STRDATA data;
} PARAM2STR, *LPPARAM2STR;
typedef const PARAM2STR *LPCPARAM2STR;

#define SERIALUI_TABLESIZE(x) ((sizeof (x))/(sizeof (x[0])))

static PARAM2STRDATA SERIALUI_Baud2StrData[]={
  {110, "110"}, {300, "300"}, {600, "600"}, {1200, "1200"},
  {2400, "2400"}, {4800, "4800"}, {9600, "9600"}, {14400, "14400"},
  {19200, "19200"}, {38400L, "38400"}, {56000L, "56000"}, {57600L, "57600"},
  {115200L, "115200"}, {128000L, "128000"}, {256000L, "256000"}
};
static PARAM2STR SERIALUI_Baud2Str={ SERIALUI_TABLESIZE(SERIALUI_Baud2StrData),SERIALUI_Baud2StrData };

static PARAM2STRDATA SERIALUI_Parity2StrData[]={
  {NOPARITY,"None"}, {ODDPARITY,"Odd"}, {EVENPARITY,"Even"}, {MARKPARITY,"Mark"},
  {SPACEPARITY,"Space"}
};
static PARAM2STR SERIALUI_Parity2Str={ SERIALUI_TABLESIZE(SERIALUI_Parity2StrData),SERIALUI_Parity2StrData };

static PARAM2STRDATA SERIALUI_Stop2StrData[]={
  {ONESTOPBIT,"1"}, {ONE5STOPBITS,"1.5"}, {TWOSTOPBITS,"2"}
};
static PARAM2STR SERIALUI_Stop2Str={ SERIALUI_TABLESIZE(SERIALUI_Stop2StrData),SERIALUI_Stop2StrData };

static PARAM2STRDATA SERIALUI_Data2StrData[]={
  {5,"5"}, {6,"6"}, {7,"7"}, {8, "8"}, {16,"16"}
};
static PARAM2STR SERIALUI_Data2Str={ SERIALUI_TABLESIZE(SERIALUI_Data2StrData),SERIALUI_Data2StrData };

static PARAM2STRDATA SERIALUI_Flow2StrData[]={
  {0,"None"}, {1,"Hardware (RTS/CTS)"}, {2,"Software (XON/XOFF)"}
};
static PARAM2STR SERIALUI_Flow2Str={ SERIALUI_TABLESIZE(SERIALUI_Flow2StrData),SERIALUI_Flow2StrData };

/*
 * Add all the fields to a combo box and highlight the current value
 */
static void SERIALUI_AddConfItems(HWND hDlg, DWORD id, LPCPARAM2STR table, DWORD dwVal)
{
    unsigned int i;
    int n;
    HWND hControl = GetDlgItem(hDlg,id);

    if(!hControl)
        return;

    for(i=0; i<table->dwSize; i++)
    {
        n = SendMessageA(hControl, CB_ADDSTRING, 0L, (LPARAM)table->data[i].name);
        if(dwVal == table->data[i].val)
	{
            SendMessageA(hControl, CB_SETCURSEL, (WPARAM)n, (LPARAM)0);
	}
    }
}

/*
 * Get the current sellection of the given combo box and set a DCB field to
 * the value matching that selection.
 */
static BOOL SERIALUI_GetConfItems(HWND hDlg, DWORD id, LPCPARAM2STR table, LPDWORD lpdwVal)
{
    DWORD i;
    CHAR lpEntry[20];
    HWND hControl = GetDlgItem(hDlg,id);

    if( (!hControl) || (!lpdwVal))
    {
        TRACE("Couldn't get window handle for item %x\n",id);
        return FALSE;
    }

    if(!GetWindowTextA(hControl, &lpEntry[0], sizeof(lpEntry)))
    {
        TRACE("Couldn't get window text for item %x\n",id);
        return FALSE;
    }
    /* TRACE("%ld contains %s\n",id, lpEntry); */

    for(i=0; i<table->dwSize; i++)
    {
        if(!lstrcmpA(table->data[i].name,lpEntry))
	{
            *lpdwVal = table->data[i].val;
            return TRUE;
	}
    }

    return FALSE;
}

/*
 * Both the enumerated values CBR_XXXX and integer baud rates are valid
 * dcb.BaudRate. This code is to convert back and forth between CBR_ style
 * and integers. The dialog box uses integer values.
 */
static const DWORD SERIALUI_BaudConvertTable[] =  {
  CBR_110, 110, CBR_300, 300, CBR_600, 600, CBR_1200, 1200,
  CBR_2400, 2400, CBR_4800, 4800, CBR_9600, 9600, CBR_14400, 14400,
  CBR_19200, 19200, CBR_38400, 38400, CBR_56000, 56000, CBR_57600, 57600,
  CBR_115200, 115200, CBR_128000, 128000, CBR_256000, 256000
};

static BOOL SERIALUI_MakeBaudDword(LPDWORD lpdwBaudRate)
{
    unsigned int i;

    for(i=0; i<(sizeof(SERIALUI_BaudConvertTable)/sizeof(DWORD)); i+=2)
    {
        if(*lpdwBaudRate == SERIALUI_BaudConvertTable[i])
        {
            *lpdwBaudRate = SERIALUI_BaudConvertTable[i+1];
            return TRUE;
        }
    }
    return FALSE;
}

static BOOL SERIALUI_MakeBaudEnum(LPDWORD lpdwBaudRate)
{
    unsigned int i;

    for(i=0; i<(sizeof(SERIALUI_BaudConvertTable)/sizeof(DWORD)); i+=2)
    {
        if(*lpdwBaudRate == SERIALUI_BaudConvertTable[i+1])
        {
            *lpdwBaudRate = SERIALUI_BaudConvertTable[i];
            return TRUE;
        }
    }
    return FALSE;
}

typedef struct tagSERIALUI_DialogInfo
{
    LPCWSTR lpszDevice;
    LPCOMMCONFIG lpCommConfig;
    BOOL bConvert; /* baud rate was converted to a DWORD */
    DWORD dwFlowControl; /* old flow control */
} SERIALUI_DialogInfo;

static void SERIALUI_DCBToDialogInfo(HWND hDlg, SERIALUI_DialogInfo *info)
{
    DWORD dwBaudRate, dwStopBits, dwParity, dwByteSize, dwFlowControl;
    LPDCB lpdcb = &info->lpCommConfig->dcb;

    /* pass integer pointers to SERIALUI_ dialog config fns */
    dwBaudRate    = lpdcb->BaudRate;
    dwStopBits    = lpdcb->StopBits;
    dwParity      = lpdcb->Parity;
    dwByteSize    = lpdcb->ByteSize;

    /* map flow control state, if it looks normal */
    if((lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE) ||
       (lpdcb->fOutxCtsFlow)) {
        dwFlowControl = 1;
    } else if(lpdcb->fOutX || lpdcb->fInX) {
        dwFlowControl = 2;
    } else {
        dwFlowControl = 0;
    }

    info->bConvert = SERIALUI_MakeBaudDword(&dwBaudRate);

    SERIALUI_AddConfItems( hDlg, IDC_BAUD, &SERIALUI_Baud2Str ,dwBaudRate);
    SERIALUI_AddConfItems( hDlg, IDC_STOP, &SERIALUI_Stop2Str ,dwStopBits);
    SERIALUI_AddConfItems( hDlg, IDC_PARITY, &SERIALUI_Parity2Str ,dwParity);
    SERIALUI_AddConfItems( hDlg, IDC_DATA, &SERIALUI_Data2Str ,dwByteSize);
    SERIALUI_AddConfItems( hDlg, IDC_FLOW, &SERIALUI_Flow2Str, dwFlowControl );

    info->dwFlowControl = dwFlowControl;
}

static void SERIALUI_DialogInfoToDCB(HWND hDlg, SERIALUI_DialogInfo *info)
{
    DWORD dwBaudRate, dwStopBits, dwParity, dwByteSize, dwFlowControl;
    LPDCB lpdcb = &info->lpCommConfig->dcb;

    SERIALUI_GetConfItems( hDlg, IDC_BAUD, &SERIALUI_Baud2Str, &dwBaudRate);
    SERIALUI_GetConfItems( hDlg, IDC_STOP, &SERIALUI_Stop2Str, &dwStopBits);
    SERIALUI_GetConfItems( hDlg, IDC_PARITY, &SERIALUI_Parity2Str, &dwParity);
    SERIALUI_GetConfItems( hDlg, IDC_DATA, &SERIALUI_Data2Str, &dwByteSize);
    SERIALUI_GetConfItems( hDlg, IDC_FLOW, &SERIALUI_Flow2Str, &dwFlowControl );

    TRACE("baud=%d stop=%d parity=%d data=%d flow=%d\n",
          dwBaudRate, dwStopBits, dwParity, dwByteSize, dwFlowControl);

    lpdcb->BaudRate = dwBaudRate;
    lpdcb->StopBits = dwStopBits;
    lpdcb->Parity   = dwParity;
    lpdcb->ByteSize = dwByteSize;

    /* try not to change flow control if the user didn't change it */
    if(info->dwFlowControl != dwFlowControl)
    {
        switch(dwFlowControl)
        {
        case 0:
            lpdcb->fOutxCtsFlow = FALSE;
            lpdcb->fOutxDsrFlow = FALSE;
            lpdcb->fDtrControl  = DTR_CONTROL_DISABLE;
            lpdcb->fOutX        = FALSE;
            lpdcb->fInX         = FALSE;
            lpdcb->fRtsControl  = RTS_CONTROL_DISABLE;
            break;
        case 1: /* CTS/RTS */
            lpdcb->fOutxCtsFlow = TRUE;
            lpdcb->fOutxDsrFlow = FALSE;
            lpdcb->fDtrControl  = DTR_CONTROL_DISABLE;
            lpdcb->fOutX        = FALSE;
            lpdcb->fInX         = FALSE;
            lpdcb->fRtsControl  = RTS_CONTROL_HANDSHAKE;
            break;
        case 2:
            lpdcb->fOutxCtsFlow = FALSE;
            lpdcb->fOutxDsrFlow = FALSE;
            lpdcb->fDtrControl  = DTR_CONTROL_DISABLE;
            lpdcb->fOutX        = TRUE;
            lpdcb->fInX         = TRUE;
            lpdcb->fRtsControl  = RTS_CONTROL_DISABLE;
            break;
        }
    }

    if(info->bConvert)
        SERIALUI_MakeBaudEnum(&lpdcb->BaudRate);
}

/***********************************************************************
 * SERIALUI_ConfigDialogProc
 *
 * Shows a dialog for configuring a COMM port
 */
static INT_PTR CALLBACK SERIALUI_ConfigDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static const WCHAR szSettings[] = {
        'S','e','t','t','i','n','g','s',' ','f','o','r',' ',0
    };
    WCHAR szTitle[40];
    SERIALUI_DialogInfo *info;

    switch (uMsg)
    {
    case WM_INITDIALOG:
        info = (SERIALUI_DialogInfo*) lParam;
        if(!info)
            return FALSE;
        SetWindowLongPtrW(hWnd, DWLP_USER, lParam);
        strcpyW( szTitle, szSettings );
        strcatW( szTitle, info->lpszDevice );
        SetWindowTextW(hWnd, szTitle);
        SERIALUI_DCBToDialogInfo(hWnd, info);
        return TRUE;

    case WM_COMMAND:
    {
        WORD wID = LOWORD(wParam);

        info = (SERIALUI_DialogInfo *) GetWindowLongPtrW(hWnd, DWLP_USER);
        if(!info)
            EndDialog(hWnd,0);
        switch (wID)
        {
        case IDOK:
            SERIALUI_DialogInfoToDCB(hWnd,info);
            EndDialog(hWnd, ERROR_SUCCESS);
            return TRUE;
        case IDCANCEL:
            EndDialog(hWnd, ERROR_CANCELLED);
            return TRUE;
/* test code for Get/SetDefaultCommConfig begins */
        case ID_GETDEFAULT:
            {
                DWORD r,dwConfSize = sizeof (COMMCONFIG);
                r = GetDefaultCommConfigW(info->lpszDevice,
                          info->lpCommConfig, &dwConfSize);
                if(!r)
                    MessageBoxA(hWnd,"Failed","GetDefaultCommConfig",MB_OK);
            }
            SERIALUI_DCBToDialogInfo(hWnd, info);
            break;
        case ID_SETDEFAULT:
            {
                DWORD r;
                SERIALUI_DialogInfoToDCB(hWnd,info);
                r = SetDefaultCommConfigW(info->lpszDevice,
                          info->lpCommConfig, sizeof (COMMCONFIG));
                if(!r)
                    MessageBoxA(hWnd,"Failed","GetDefaultCommConfig",MB_OK);
            }
            break;
/* test code for Get/SetDefaultCommConfig ends */
        }
    }
    default:
        return FALSE;
    }
}

static LPWSTR SERIALUI_strdup( LPCSTR str )
{
    DWORD len;
    LPWSTR strW;

    if (!str)
        return NULL;
    len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
    strW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
    MultiByteToWideChar( CP_ACP, 0, str, -1, strW, len );
    return strW;
}

static VOID SERIALUI_strfree( LPWSTR strW )
{
    HeapFree( GetProcessHeap(), 0, strW );
}

/***********************************************************************
 * drvCommConfigDialogW (SERIALUI.@)
 *
 * Show a dialog for configuring a Serial Port.
 *
 */
DWORD WINAPI drvCommConfigDialogW(LPCWSTR lpszName, HWND hWndParent, LPCOMMCONFIG lpCommConfig)
{
    SERIALUI_DialogInfo info;
    INT res;

    info.lpCommConfig  = lpCommConfig;
    info.lpszDevice    = lpszName;
    info.bConvert      = FALSE;
    info.dwFlowControl = 0;

    if ((!lpCommConfig) || (!lpszName))
        return ERROR_INVALID_PARAMETER;

    if (lpCommConfig->dwSize < sizeof(COMMCONFIG))
        return ERROR_INSUFFICIENT_BUFFER;

    if (!lpszName[0])
        return ERROR_BADKEY;

    res = DialogBoxParamW( SERIALUI_hModule,
                           MAKEINTRESOURCEW(IDD_SERIALUICONFIG),
                           hWndParent,
                           SERIALUI_ConfigDialogProc,
                           (LPARAM)&info);

    return (res == -1) ? GetLastError() : res ;
}

/***********************************************************************
 * drvCommConfigDialogA (SERIALUI.@)
 */
DWORD WINAPI drvCommConfigDialogA(LPCSTR lpszName, HWND hWndParent, LPCOMMCONFIG lpCommConfig)
{
    LPWSTR strW = SERIALUI_strdup( lpszName );
    DWORD r = drvCommConfigDialogW( strW, hWndParent, lpCommConfig );
    SERIALUI_strfree( strW );
    return r;
}

static const WCHAR lpszCommKey[] = {
    'S','y','s','t','e','m','\\',
    'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
    'S','e','r','v','i','c','e','s','\\',
    'C','l','a','s','s','\\','P','o','r','t','s',0
};
static const WCHAR lpszDCB[]     = {'D','C','B',0};

/***********************************************************************
 * drvSetDefaultCommConfigW (SERIALUI.@)
 *
 * Used by Win98 KERNEL to set the default config for a COMM port
 * FIXME: uses the wrong registry key... should use a digit, not
 *        the comm port name.
 */
BOOL WINAPI drvSetDefaultCommConfigW(
	LPCWSTR lpszDevice, LPCOMMCONFIG lpCommConfig, DWORD dwSize)
{
    HKEY hKeyReg=0, hKeyPort=0;
    WCHAR szKeyName[100];
    DWORD r,dwDCBSize;
    static const WCHAR fmt[] = {'%','s','\\','%','s',0 };

    TRACE("%p %p %x\n",lpszDevice,lpCommConfig,dwSize);

    if(!lpCommConfig)
        return FALSE;

    if(dwSize < sizeof (COMMCONFIG))
        return FALSE;

    r = RegConnectRegistryW(NULL, HKEY_LOCAL_MACHINE, &hKeyReg);
    if(r != ERROR_SUCCESS)
        return FALSE;

    snprintfW(szKeyName, sizeof(szKeyName)/sizeof(WCHAR), fmt, lpszCommKey ,lpszDevice);
    r = RegCreateKeyW(hKeyReg, szKeyName, &hKeyPort);
    if(r == ERROR_SUCCESS)
    {
        dwDCBSize = sizeof (DCB);
        r = RegSetValueExW( hKeyPort, lpszDCB, 0, REG_BINARY,
                            (LPBYTE)&lpCommConfig->dcb,dwDCBSize);
        TRACE("write key r=%d\n",r);
        RegCloseKey(hKeyPort);
    }

    RegCloseKey(hKeyReg);

    return (r==ERROR_SUCCESS);
}

/***********************************************************************
 * drvSetDefaultCommConfigA (SERIALUI.@)
 */
BOOL WINAPI drvSetDefaultCommConfigA(
	LPCSTR lpszDevice, LPCOMMCONFIG lpCommConfig, DWORD dwSize)
{
    LPWSTR strW = SERIALUI_strdup( lpszDevice );
    BOOL r = drvSetDefaultCommConfigW( strW, lpCommConfig, dwSize );
    SERIALUI_strfree( strW );
    return r;
}

/***********************************************************************
 * drvGetDefaultCommConfigW (SERIALUI.@)
 *
 * Used by Win9x KERNEL to get the default config for a COMM port
 * FIXME: uses the wrong registry key... should use a digit, not
 *        the comm port name.
 */
DWORD WINAPI drvGetDefaultCommConfigW(
	LPCWSTR lpszDevice, LPCOMMCONFIG lpCommConfig, LPDWORD lpdwSize)
{
    HKEY hKeyReg, hKeyPort;
    WCHAR szKeyName[100];
    DWORD r,dwSize,dwType;
    static const WCHAR fmt[] = {'%','s','\\','%','s',0 };

    TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_w(lpszDevice), lpCommConfig, lpdwSize, lpdwSize ? *lpdwSize : 0);

    if ((!lpszDevice) || (!lpCommConfig) || (!lpdwSize)) {
        return ERROR_INVALID_PARAMETER;
    }

    if (*lpdwSize < sizeof (COMMCONFIG)) {
        *lpdwSize = sizeof (COMMCONFIG);
        return ERROR_INSUFFICIENT_BUFFER;
    }

    /* only "com1" - "com9" is allowed */
    r = sizeof(comW) / sizeof(WCHAR);       /* len of "com\0" */
    lstrcpynW(szKeyName, lpszDevice, r);    /* simulate a lstrcmpnW */
    r--;

    if( lstrcmpiW(szKeyName, comW) ||
        (lpszDevice[r] < '1') || (lpszDevice[r] > '9') || lpszDevice[r+1]) {
        return ERROR_BADKEY;
    }

    *lpdwSize = sizeof (COMMCONFIG);
    memset(lpCommConfig, 0 , sizeof (COMMCONFIG));
    lpCommConfig->dwSize = sizeof (COMMCONFIG);
    lpCommConfig->wVersion = 1;
    lpCommConfig->dwProviderSubType = PST_RS232;

    r = RegConnectRegistryW(NULL, HKEY_LOCAL_MACHINE, &hKeyReg);
    if(r != ERROR_SUCCESS) return r;

    snprintfW(szKeyName, sizeof(szKeyName)/sizeof(WCHAR), fmt, lpszCommKey ,lpszDevice);
    r = RegOpenKeyW(hKeyReg, szKeyName, &hKeyPort);
    if(r == ERROR_SUCCESS)
    {
        dwSize = sizeof (DCB);
        dwType = 0;
        r = RegQueryValueExW( hKeyPort, lpszDCB, NULL,
                             &dwType, (LPBYTE)&lpCommConfig->dcb, &dwSize);

        RegCloseKey(hKeyPort);
        if ((r!=ERROR_SUCCESS) || (dwType != REG_BINARY) || (dwSize != sizeof(DCB))) {
            RegCloseKey(hKeyReg);
            return ERROR_INVALID_PARAMETER;
        }

    }
    else
    {
        /* FIXME: default to a hardcoded commconfig */
        lpCommConfig->dcb.DCBlength = sizeof(DCB);
        lpCommConfig->dcb.BaudRate = 9600;
        lpCommConfig->dcb.fBinary = TRUE;
        lpCommConfig->dcb.fParity = FALSE;
        lpCommConfig->dcb.ByteSize = 8;
        lpCommConfig->dcb.Parity = NOPARITY;
        lpCommConfig->dcb.StopBits = ONESTOPBIT;
        return ERROR_SUCCESS;
    }

    RegCloseKey(hKeyReg);

    return r;
}

/***********************************************************************
 * drvGetDefaultCommConfigA (SERIALUI.@)
 */
DWORD WINAPI drvGetDefaultCommConfigA(
	LPCSTR lpszDevice, LPCOMMCONFIG lpCommConfig, LPDWORD lpdwSize)
{
    LPWSTR strW = SERIALUI_strdup( lpszDevice );
    DWORD r = drvGetDefaultCommConfigW( strW, lpCommConfig, lpdwSize );
    SERIALUI_strfree( strW );
    return r;
}
