/*
 * Implementation of the Local Printmonitor
 *
 * Copyright 2006 Detlef Riekenberg
 *
 * 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 <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"

#include "winspool.h"
#include "ddk/winsplp.h"
#include "localspl_private.h"

#include "wine/debug.h"
#include "wine/list.h"
#include "wine/unicode.h"


WINE_DEFAULT_DEBUG_CHANNEL(localspl);

/*****************************************************/

static CRITICAL_SECTION port_handles_cs;
static CRITICAL_SECTION_DEBUG port_handles_cs_debug =
{
    0, 0, &port_handles_cs,
    { &port_handles_cs_debug.ProcessLocksList, &port_handles_cs_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": port_handles_cs") }
};
static CRITICAL_SECTION port_handles_cs = { &port_handles_cs_debug, -1, 0, 0, 0, 0 };


static CRITICAL_SECTION xcv_handles_cs;
static CRITICAL_SECTION_DEBUG xcv_handles_cs_debug =
{
    0, 0, &xcv_handles_cs,
    { &xcv_handles_cs_debug.ProcessLocksList, &xcv_handles_cs_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": xcv_handles_cs") }
};
static CRITICAL_SECTION xcv_handles_cs = { &xcv_handles_cs_debug, -1, 0, 0, 0, 0 };

/* ############################### */

typedef struct {
    struct list entry;
    DWORD   type;
    WCHAR   nameW[1];
} port_t;

typedef struct {
    struct list entry;
    ACCESS_MASK GrantedAccess;
    WCHAR       nameW[1];
} xcv_t;

static struct list port_handles = LIST_INIT( port_handles );
static struct list xcv_handles = LIST_INIT( xcv_handles );

/* ############################### */

static const WCHAR cmd_AddPortW[] = {'A','d','d','P','o','r','t',0};
static const WCHAR cmd_DeletePortW[] = {'D','e','l','e','t','e','P','o','r','t',0};
static const WCHAR cmd_ConfigureLPTPortCommandOKW[] = {'C','o','n','f','i','g','u','r','e',
                                    'L','P','T','P','o','r','t',
                                    'C','o','m','m','a','n','d','O','K',0};

static const WCHAR cmd_GetDefaultCommConfigW[] = {'G','e','t',
                                    'D','e','f','a','u','l','t',
                                    'C','o','m','m','C','o','n','f','i','g',0};

static const WCHAR cmd_GetTransmissionRetryTimeoutW[] = {'G','e','t',
                                    'T','r','a','n','s','m','i','s','s','i','o','n',
                                    'R','e','t','r','y','T','i','m','e','o','u','t',0};

static const WCHAR cmd_MonitorUIW[] = {'M','o','n','i','t','o','r','U','I',0};
static const WCHAR cmd_PortIsValidW[] = {'P','o','r','t','I','s','V','a','l','i','d',0};
static const WCHAR cmd_SetDefaultCommConfigW[] = {'S','e','t',
                                    'D','e','f','a','u','l','t',
                                    'C','o','m','m','C','o','n','f','i','g',0};

static const WCHAR dllnameuiW[] = {'l','o','c','a','l','u','i','.','d','l','l',0};
static const WCHAR emptyW[] = {0};
static const WCHAR LocalPortW[] = {'L','o','c','a','l',' ','P','o','r','t',0};

static const WCHAR portname_LPT[]  = {'L','P','T',0};
static const WCHAR portname_COM[]  = {'C','O','M',0};
static const WCHAR portname_FILE[] = {'F','I','L','E',':',0};
static const WCHAR portname_CUPS[] = {'C','U','P','S',':',0};
static const WCHAR portname_LPR[]  = {'L','P','R',':',0};

static const WCHAR TransmissionRetryTimeoutW[] = {'T','r','a','n','s','m','i','s','s','i','o','n',
                                    'R','e','t','r','y','T','i','m','e','o','u','t',0};

static const WCHAR WinNT_CV_PortsW[] = {'S','o','f','t','w','a','r','e','\\',
                                        'M','i','c','r','o','s','o','f','t','\\',
                                        'W','i','n','d','o','w','s',' ','N','T','\\',
                                        'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
                                        'P','o','r','t','s',0};

static const WCHAR WinNT_CV_WindowsW[] = {'S','o','f','t','w','a','r','e','\\',
                                        'M','i','c','r','o','s','o','f','t','\\',
                                        'W','i','n','d','o','w','s',' ','N','T','\\',
                                        'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
                                        'W','i','n','d','o','w','s',0};


/******************************************************************
 * does_port_exist (internal)
 *
 * returns TRUE, when the Port already exists
 *
 */
static BOOL does_port_exist(LPCWSTR myname)
{

    LPPORT_INFO_1W  pi;
    DWORD   needed = 0;
    DWORD   returned;
    DWORD   id;

    TRACE("(%s)\n", debugstr_w(myname));

    id = EnumPortsW(NULL, 1, NULL, 0, &needed, &returned);
    pi = heap_alloc(needed);
    returned = 0;
    if (pi)
        id = EnumPortsW(NULL, 1, (LPBYTE) pi, needed, &needed, &returned);

    if (id && returned > 0) {
        /* we got a number of valid names. */
        for (id = 0; id < returned; id++)
        {
            if (lstrcmpiW(myname, pi[id].pName) == 0) {
                TRACE("(%u) found %s\n", id, debugstr_w(pi[id].pName));
                heap_free(pi);
                return TRUE;
            }
        }
    }

    heap_free(pi);
    return FALSE;
}

/******************************************************************
 * enumerate the local Ports from the Registry (internal)  
 *
 * See localmon_EnumPortsW.
 *
 * NOTES
 *  returns the needed size (in bytes) for pPorts
 *  and *lpreturned is set to number of entries returned in pPorts
 *
 */

static DWORD get_ports_from_reg(DWORD level, LPBYTE pPorts, DWORD cbBuf, LPDWORD lpreturned)
{
    HKEY    hroot = 0;
    LPWSTR  ptr;
    LPPORT_INFO_2W out;
    WCHAR   portname[MAX_PATH];
    WCHAR   res_PortW[IDS_LOCALPORT_MAXLEN];
    WCHAR   res_MonitorW[IDS_LOCALMONITOR_MAXLEN];
    INT     reslen_PortW;
    INT     reslen_MonitorW;
    DWORD   len;
    DWORD   res;
    DWORD   needed = 0;
    DWORD   numentries;
    DWORD   entrysize;
    DWORD   id = 0;

    TRACE("(%d, %p, %d, %p)\n", level, pPorts, cbBuf, lpreturned);

    entrysize = (level == 1) ? sizeof(PORT_INFO_1W) : sizeof(PORT_INFO_2W);

    numentries = *lpreturned;           /* this is 0, when we scan the registry */
    needed = entrysize * numentries;
    ptr = (LPWSTR) &pPorts[needed];

    if (needed > cbBuf) pPorts = NULL;  /* No buffer for the structs */

    numentries = 0;
    needed = 0;

    /* we do not check more parameters as done in windows */
    if ((level < 1) || (level > 2)) {
        goto getports_cleanup;
    }

    /* "+1" for '\0' */
    reslen_MonitorW = LoadStringW(LOCALSPL_hInstance, IDS_LOCALMONITOR, res_MonitorW, IDS_LOCALMONITOR_MAXLEN) + 1;  
    reslen_PortW = LoadStringW(LOCALSPL_hInstance, IDS_LOCALPORT, res_PortW, IDS_LOCALPORT_MAXLEN) + 1;  

    res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot);
    if (res == ERROR_SUCCESS) {

        /* Scan all Port-Names */
        while (res == ERROR_SUCCESS) {
            len = MAX_PATH;
            portname[0] = '\0';
            res = RegEnumValueW(hroot, id, portname, &len, NULL, NULL, NULL, NULL);

            if ((res == ERROR_SUCCESS) && (portname[0])) {
                numentries++;
                /* calculate the required size */
                needed += entrysize;
                needed += (len + 1) * sizeof(WCHAR);
                if (level > 1) {
                    needed += (reslen_MonitorW + reslen_PortW) * sizeof(WCHAR);
                }

                /* Now fill the user-buffer, if available */
                if (pPorts && (cbBuf >= needed)){
                    out = (LPPORT_INFO_2W) pPorts;
                    pPorts += entrysize;
                    TRACE("%p: writing PORT_INFO_%dW #%d (%s)\n", out, level, numentries, debugstr_w(portname));
                    out->pPortName = ptr;
                    lstrcpyW(ptr, portname);            /* Name of the Port */
                    ptr += (len + 1);
                    if (level > 1) {
                        out->pMonitorName = ptr;
                        lstrcpyW(ptr, res_MonitorW);    /* Name of the Monitor */
                        ptr += reslen_MonitorW;

                        out->pDescription = ptr;
                        lstrcpyW(ptr, res_PortW);       /* Port Description */
                        ptr += reslen_PortW;

                        out->fPortType = PORT_TYPE_WRITE;
                        out->Reserved = 0;
                    }
                }
                id++;
            }
        }
        RegCloseKey(hroot);
    }
    else
    {
        ERR("failed with %d for %s\n", res, debugstr_w(WinNT_CV_PortsW));
        SetLastError(res);
    }

getports_cleanup:
    *lpreturned = numentries;
    TRACE("need %d byte for %d entries (%d)\n", needed, numentries, GetLastError());
    return needed;
}

/*****************************************************
 * get_type_from_name (internal)
 * 
 */

static DWORD get_type_from_name(LPCWSTR name)
{
    HANDLE  hfile;

    if (!strncmpW(name, portname_LPT, sizeof(portname_LPT) / sizeof(WCHAR) -1))
        return PORT_IS_LPT;

    if (!strncmpW(name, portname_COM, sizeof(portname_COM) / sizeof(WCHAR) -1))
        return PORT_IS_COM;

    if (!strcmpW(name, portname_FILE))
        return PORT_IS_FILE;

    if (name[0] == '/')
        return PORT_IS_UNIXNAME;

    if (name[0] == '|')
        return PORT_IS_PIPE;

    if (!strncmpW(name, portname_CUPS, sizeof(portname_CUPS) / sizeof(WCHAR) -1))
        return PORT_IS_CUPS;

    if (!strncmpW(name, portname_LPR, sizeof(portname_LPR) / sizeof(WCHAR) -1))
        return PORT_IS_LPR;

    /* Must be a file or a directory. Does the file exist ? */
    hfile = CreateFileW(name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    TRACE("%p for OPEN_EXISTING on %s\n", hfile, debugstr_w(name));
    if (hfile == INVALID_HANDLE_VALUE) {
        /* Can we create the file? */
        hfile = CreateFileW(name, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
        TRACE("%p for OPEN_ALWAYS\n", hfile);
    }
    if (hfile != INVALID_HANDLE_VALUE) {
        CloseHandle(hfile);
        return PORT_IS_FILENAME;
    }
    /* We can't use the name. use GetLastError() for the reason */
    return PORT_IS_UNKNOWN;
}

/*****************************************************
 * get_type_from_local_name (internal)
 *
 */

static DWORD get_type_from_local_name(LPCWSTR nameW)
{
    LPPORT_INFO_1W  pi;
    LPWSTR  myname = NULL;
    DWORD   needed = 0;
    DWORD   numentries = 0;
    DWORD   id = 0;

    TRACE("(%s)\n", debugstr_w(myname));

    needed = get_ports_from_reg(1, NULL, 0, &numentries);
    pi = heap_alloc(needed);
    if (pi)
        needed = get_ports_from_reg(1, (LPBYTE) pi, needed, &numentries);

    if (pi && needed && numentries > 0) {
        /* we got a number of valid ports. */

        while ((myname == NULL) && (id < numentries))
        {
            if (lstrcmpiW(nameW, pi[id].pName) == 0) {
                TRACE("(%u) found %s\n", id, debugstr_w(pi[id].pName));
                myname = pi[id].pName;
            }
            id++;
        }
    }

    id = (myname) ? get_type_from_name(myname) : PORT_IS_UNKNOWN;

    heap_free(pi);
    return id;

}
/******************************************************************************
 *   localmon_AddPortExW [exported through MONITOREX]
 *
 * Add a Port, without presenting a user interface
 *
 * PARAMS
 *  pName         [I] Servername or NULL (local Computer)
 *  level         [I] Structure-Level (1) for pBuffer
 *  pBuffer       [I] PTR to the Input-Data (PORT_INFO_1)
 *  pMonitorName  [I] Name of the Monitor that manage the Port
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 * NOTES
 *  Level 2 is documented on MSDN for Portmonitors, but not supported by the
 *  "Local Port" Portmonitor (localspl.dll / localmon.dll)
 */
static BOOL WINAPI localmon_AddPortExW(LPWSTR pName, DWORD level, LPBYTE pBuffer, LPWSTR pMonitorName)
{
    PORT_INFO_1W * pi;
    HKEY  hroot;
    DWORD res;

    pi = (PORT_INFO_1W *) pBuffer;
    TRACE("(%s, %d, %p, %s) => %s\n", debugstr_w(pName), level, pBuffer,
            debugstr_w(pMonitorName), debugstr_w(pi ? pi->pName : NULL));


    if ((pMonitorName == NULL) || (lstrcmpiW(pMonitorName, LocalPortW) != 0 ) ||
        (pi == NULL) || (pi->pName == NULL) || (pi->pName[0] == '\0') ) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (level != 1) {
        SetLastError(ERROR_INVALID_LEVEL);
        return FALSE;
    }

    res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot);
    if (res == ERROR_SUCCESS) {
        if (does_port_exist(pi->pName)) {
            RegCloseKey(hroot);
            TRACE("=> FALSE with %u\n", ERROR_INVALID_PARAMETER);
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
        }
        res = RegSetValueExW(hroot, pi->pName, 0, REG_SZ, (const BYTE *) emptyW, sizeof(emptyW));
        RegCloseKey(hroot);
    }
    if (res != ERROR_SUCCESS) SetLastError(ERROR_INVALID_PARAMETER);
    TRACE("=> %u with %u\n", (res == ERROR_SUCCESS), GetLastError());
    return (res == ERROR_SUCCESS);
}

/*****************************************************
 * localmon_ClosePort [exported through MONITOREX]
 *
 * Close a
 *
 * PARAMS
 *  hPort  [i] The Handle to close
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 */
static BOOL WINAPI localmon_ClosePort(HANDLE hPort)
{
    port_t * port = hPort;

    TRACE("(%p)\n", port);
    EnterCriticalSection(&port_handles_cs);
    list_remove(&port->entry);
    LeaveCriticalSection(&port_handles_cs);
    heap_free(port);
    return TRUE;
}

/*****************************************************
 *   localmon_EnumPortsW [exported through MONITOREX]
 *
 * Enumerate all local Ports
 *
 * PARAMS
 *  pName       [I] Servername (ignored)
 *  level       [I] Structure-Level (1 or 2)
 *  pPorts      [O] PTR to Buffer that receives the Result
 *  cbBuf       [I] Size of Buffer at pPorts
 *  pcbNeeded   [O] PTR to DWORD that receives the size in Bytes used / required for pPorts
 *  pcReturned  [O] PTR to DWORD that receives the number of Ports in pPorts
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE and in pcbNeeded the Bytes required for pPorts, if cbBuf is too small
 *
 * NOTES
 *|  Windows ignores pName
 *|  Windows crash the app, when pPorts, pcbNeeded or pcReturned are NULL
 *|  Windows >NT4.0 does not check for illegal levels (TRUE is returned)
 *
 * ToDo
 *   "HCU\Software\Wine\Spooler\<portname>" - redirection
 *
 */
static BOOL WINAPI localmon_EnumPortsW(LPWSTR pName, DWORD level, LPBYTE pPorts,
                                       DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
{
    BOOL    res = FALSE;
    DWORD   needed;
    DWORD   numentries;

    TRACE("(%s, %d, %p, %d, %p, %p)\n",
          debugstr_w(pName), level, pPorts, cbBuf, pcbNeeded, pcReturned);

    numentries = 0;
    needed = get_ports_from_reg(level, NULL, 0, &numentries);
    /* we calculated the needed buffersize. now do the error-checks */
    if (cbBuf < needed) {
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        goto cleanup;
    }

    /* fill the buffer with the Port-Names */
    needed = get_ports_from_reg(level, pPorts, cbBuf, &numentries);
    res = TRUE;

    if (pcReturned) *pcReturned = numentries;

cleanup:
    if (pcbNeeded)  *pcbNeeded = needed;

    TRACE("returning %d with %d (%d byte for %d entries)\n", 
            res, GetLastError(), needed, numentries);

    return (res);
}

/*****************************************************
 * localmon_OpenPort [exported through MONITOREX]
 *
 * Open a Data-Channel for a Port
 *
 * PARAMS
 *  pName     [i] Name of selected Object
 *  phPort    [o] The resulting Handle is stored here
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 */
static BOOL WINAPI localmon_OpenPortW(LPWSTR pName, PHANDLE phPort)
{
    port_t * port;
    DWORD   type;

    TRACE("%s, %p)\n", debugstr_w(pName), phPort);

    /* an empty name is invalid */
    if (!pName[0]) return FALSE;

    /* does the port exist? */
    type = get_type_from_local_name(pName);
    if (!type) return FALSE;

    port = heap_alloc(FIELD_OFFSET(port_t, nameW[lstrlenW(pName) + 1]));
    if (!port) return FALSE;

    port->type = type;
    lstrcpyW(port->nameW, pName);
    *phPort = port;

    EnterCriticalSection(&port_handles_cs);
    list_add_tail(&port_handles, &port->entry);
    LeaveCriticalSection(&port_handles_cs);

    TRACE("=> %p\n", port);
    return TRUE;
}

/*****************************************************
 * localmon_XcvClosePort [exported through MONITOREX]
 *
 * Close a Communication-Channel
 *
 * PARAMS
 *  hXcv  [i] The Handle to close
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 */
static BOOL WINAPI localmon_XcvClosePort(HANDLE hXcv)
{
    xcv_t * xcv = hXcv;

    TRACE("(%p)\n", xcv);
    /* No checks are done in Windows */
    EnterCriticalSection(&xcv_handles_cs);
    list_remove(&xcv->entry);
    LeaveCriticalSection(&xcv_handles_cs);
    heap_free(xcv);
    return TRUE;
}

/*****************************************************
 * localmon_XcvDataPort [exported through MONITOREX]
 *
 * Execute command through a Communication-Channel
 *
 * PARAMS
 *  hXcv            [i] The Handle to work with
 *  pszDataName     [i] Name of the command to execute
 *  pInputData      [i] Buffer for extra Input Data (needed only for some commands)
 *  cbInputData     [i] Size in Bytes of Buffer at pInputData
 *  pOutputData     [o] Buffer to receive additional Data (needed only for some commands)
 *  cbOutputData    [i] Size in Bytes of Buffer at pOutputData
 *  pcbOutputNeeded [o] PTR to receive the minimal Size in Bytes of the Buffer at pOutputData
 *
 * RETURNS
 *  Success: ERROR_SUCCESS
 *  Failure: win32 error code
 *
 * NOTES
 *
 *  Minimal List of commands, that every Printmonitor DLL should support:
 *
 *| "MonitorUI" : Return the Name of the Userinterface-DLL as WSTR in pOutputData
 *| "AddPort"   : Add a Port (Name as WSTR in pInputData)
 *| "DeletePort": Delete a Port (Name as WSTR in pInputData)
 *
 *
 */
static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData,
                                         PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded)
{
    WCHAR   buffer[16];     /* buffer for a decimal number */
    LPWSTR  ptr;
    DWORD   res;
    DWORD   needed;
    HKEY    hroot;

    TRACE("(%p, %s, %p, %d, %p, %d, %p)\n", hXcv, debugstr_w(pszDataName),
          pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded);

    if (!lstrcmpW(pszDataName, cmd_AddPortW)) {
        TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData));
        res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot);
        if (res == ERROR_SUCCESS) {
            if (does_port_exist((LPWSTR) pInputData)) {
                RegCloseKey(hroot);
                TRACE("=> %u\n", ERROR_ALREADY_EXISTS);
                return ERROR_ALREADY_EXISTS;
            }
            res = RegSetValueExW(hroot, (LPWSTR) pInputData, 0, REG_SZ, (const BYTE *) emptyW, sizeof(emptyW));
            RegCloseKey(hroot);
        }
        TRACE("=> %u\n", res);
        return res;
    }


    if (!lstrcmpW(pszDataName, cmd_ConfigureLPTPortCommandOKW)) {
        TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData));
        res = RegCreateKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_WindowsW, &hroot);
        if (res == ERROR_SUCCESS) {
            res = RegSetValueExW(hroot, TransmissionRetryTimeoutW, 0, REG_SZ, pInputData, cbInputData);
            RegCloseKey(hroot);
        }
        return res;
    }

    if (!lstrcmpW(pszDataName, cmd_DeletePortW)) {
        TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData));
        res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot);
        if (res == ERROR_SUCCESS) {
            res = RegDeleteValueW(hroot, (LPWSTR) pInputData);
            RegCloseKey(hroot);
            TRACE("=> %u with %u\n", res, GetLastError() );
            return res;
        }
        return ERROR_FILE_NOT_FOUND;
    }

    if (!lstrcmpW(pszDataName, cmd_GetDefaultCommConfigW)) {
        TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData));
        *pcbOutputNeeded = cbOutputData;
        res = GetDefaultCommConfigW((LPWSTR) pInputData, (LPCOMMCONFIG) pOutputData, pcbOutputNeeded);
        TRACE("got %u with %u\n", res, GetLastError() );
        return res ? ERROR_SUCCESS : GetLastError();
    }

    if (!lstrcmpW(pszDataName, cmd_GetTransmissionRetryTimeoutW)) {
        * pcbOutputNeeded = sizeof(DWORD);
        if (cbOutputData >= sizeof(DWORD)) {
            /* the w2k resource kit documented a default of 90, but that's wrong */
            *((LPDWORD) pOutputData) = 45;

            res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_WindowsW, &hroot);
            if (res == ERROR_SUCCESS) {
                needed = sizeof(buffer) - sizeof(WCHAR);
                res = RegQueryValueExW(hroot, TransmissionRetryTimeoutW, NULL, NULL, (LPBYTE) buffer, &needed);
                if ((res == ERROR_SUCCESS) && (buffer[0])) {
                    *((LPDWORD) pOutputData) = strtoulW(buffer, NULL, 0);
                }
                RegCloseKey(hroot);
            }
            return ERROR_SUCCESS;
        }
        return ERROR_INSUFFICIENT_BUFFER;
    }


    if (!lstrcmpW(pszDataName, cmd_MonitorUIW)) {
        * pcbOutputNeeded = sizeof(dllnameuiW);
        if (cbOutputData >= sizeof(dllnameuiW)) {
            memcpy(pOutputData, dllnameuiW, sizeof(dllnameuiW));
            return ERROR_SUCCESS;
        }
        return ERROR_INSUFFICIENT_BUFFER;
    }

    if (!lstrcmpW(pszDataName, cmd_PortIsValidW)) {
        TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData));
        res = get_type_from_name((LPCWSTR) pInputData);
        TRACE("detected as %u\n",  res);
        /* names, that we have recognized, are valid */
        if (res) return ERROR_SUCCESS;

        /* ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND or something else */
        TRACE("=> %u\n", GetLastError());
        return GetLastError();
    }

    if (!lstrcmpW(pszDataName, cmd_SetDefaultCommConfigW)) {
        /* get the portname from the Handle */
        ptr =  strchrW(((xcv_t *)hXcv)->nameW, ' ');
        if (ptr) {
            ptr++;  /* skip the space */
        }
        else
        {
            ptr =  ((xcv_t *)hXcv)->nameW;
        }
        lstrcpynW(buffer, ptr, sizeof(buffer)/sizeof(WCHAR));
        if (buffer[0]) buffer[lstrlenW(buffer)-1] = '\0';  /* remove the ':' */
        res = SetDefaultCommConfigW(buffer, (LPCOMMCONFIG) pInputData, cbInputData);
        TRACE("got %u with %u\n", res, GetLastError() );
        return res ? ERROR_SUCCESS : GetLastError();
    }

    FIXME("command not supported: %s\n", debugstr_w(pszDataName));
    return ERROR_INVALID_PARAMETER;
}

/*****************************************************
 * localmon_XcvOpenPort [exported through MONITOREX]
 *
 * Open a Communication-Channel
 *
 * PARAMS
 *  pName         [i] Name of selected Object
 *  GrantedAccess [i] Access-Rights to use
 *  phXcv         [o] The resulting Handle is stored here
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 */
static BOOL WINAPI localmon_XcvOpenPort(LPCWSTR pName, ACCESS_MASK GrantedAccess, PHANDLE phXcv)
{
    xcv_t * xcv;

    TRACE("%s, 0x%x, %p)\n", debugstr_w(pName), GrantedAccess, phXcv);
    /* No checks for any field is done in Windows */
    xcv = heap_alloc(FIELD_OFFSET(xcv_t, nameW[lstrlenW(pName) + 1]));
    if (xcv) {
        xcv->GrantedAccess = GrantedAccess;
        lstrcpyW(xcv->nameW, pName);
        *phXcv = xcv;
        EnterCriticalSection(&xcv_handles_cs);
        list_add_tail(&xcv_handles, &xcv->entry);
        LeaveCriticalSection(&xcv_handles_cs);
        TRACE("=> %p\n", xcv);
        return TRUE;
    }
    else
    {
        *phXcv = NULL;
        return FALSE;
    }
}

/*****************************************************
 *      InitializePrintMonitor  (LOCALSPL.@)
 *
 * Initialize the Monitor for the Local Ports
 *
 * PARAMS
 *  regroot [I] Registry-Path, where the settings are stored
 *
 * RETURNS
 *  Success: Pointer to a MONITOREX Structure
 *  Failure: NULL
 *
 * NOTES
 *  The fixed location "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Ports"
 *  is used to store the Ports (IniFileMapping from "win.ini", Section "Ports").
 *  Native localspl.dll fails, when no valid Port-Entry is present.
 *
 */

LPMONITOREX WINAPI InitializePrintMonitor(LPWSTR regroot)
{
    static MONITOREX mymonitorex =
    {
        sizeof(MONITOREX) - sizeof(DWORD),
        {
            localmon_EnumPortsW,
            localmon_OpenPortW,
            NULL,       /* localmon_OpenPortExW */ 
            NULL,       /* localmon_StartDocPortW */
            NULL,       /* localmon_WritePortW */
            NULL,       /* localmon_ReadPortW */
            NULL,       /* localmon_EndDocPortW */
            localmon_ClosePort,
            NULL,       /* Use AddPortUI in localui.dll */
            localmon_AddPortExW,
            NULL,       /* Use ConfigurePortUI in localui.dll */
            NULL,       /* Use DeletePortUI in localui.dll */
            NULL,       /* localmon_GetPrinterDataFromPort */
            NULL,       /* localmon_SetPortTimeOuts */
            localmon_XcvOpenPort,
            localmon_XcvDataPort,
            localmon_XcvClosePort
        }
    };

    TRACE("(%s)\n", debugstr_w(regroot));
    /* Parameter "regroot" is ignored on NT4.0 (localmon.dll) */
    if (!regroot || !regroot[0]) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }
    TRACE("=> %p\n", &mymonitorex);
    /* Native windows returns always the same pointer on success */
    return &mymonitorex;
}
