/*
 * Implementation of the Local Printmonitor User Interface
 *
 * Copyright 2007 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 NONAMELESSUNION

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

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

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

WINE_DEFAULT_DEBUG_CHANNEL(localui);

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

static HINSTANCE LOCALUI_hInstance;

static const WCHAR cmd_AddPortW[] = {'A','d','d','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_DeletePortW[] = {'D','e','l','e','t','e','P','o','r','t',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_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 fmt_uW[]  = {'%','u',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 XcvMonitorW[] = {',','X','c','v','M','o','n','i','t','o','r',' ',0};
static const WCHAR XcvPortW[] = {',','X','c','v','P','o','r','t',' ',0};

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

typedef struct tag_addportui_t {
    LPWSTR  portname;
    HANDLE  hXcv;
} addportui_t;

typedef struct tag_lptconfig_t {
    HANDLE  hXcv;
    DWORD   value;
} lptconfig_t;


static INT_PTR CALLBACK dlgproc_lptconfig(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

/*****************************************************
 *   strdupWW [internal]
 */

static LPWSTR strdupWW(LPCWSTR pPrefix, LPCWSTR pSuffix)
{
    LPWSTR  ptr;
    DWORD   len;

    len = lstrlenW(pPrefix) + (pSuffix ? lstrlenW(pSuffix) : 0) + 1;
    ptr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (ptr) {
        lstrcpyW(ptr, pPrefix);
        if (pSuffix) lstrcatW(ptr, pSuffix);
    }
    return ptr;
}

/*****************************************************
 *   dlg_configure_com [internal]
 *
 */

static BOOL dlg_configure_com(HANDLE hXcv, HWND hWnd, PCWSTR pPortName)
{
    COMMCONFIG cfg;
    LPWSTR shortname;
    DWORD status;
    DWORD dummy;
    DWORD len;
    BOOL  res;

    /* strip the colon (pPortName is never empty here) */
    len = lstrlenW(pPortName);
    shortname = HeapAlloc(GetProcessHeap(), 0, len  * sizeof(WCHAR));
    if (shortname) {
        memcpy(shortname, pPortName, (len -1) * sizeof(WCHAR));
        shortname[len-1] = '\0';

        /* get current settings */
        len = FIELD_OFFSET(COMMCONFIG, wcProviderData[1]);
        status = ERROR_SUCCESS;
        res = XcvDataW( hXcv, cmd_GetDefaultCommConfigW,
                        (PBYTE) shortname,
                        (lstrlenW(shortname) +1) * sizeof(WCHAR),
                        (PBYTE) &cfg, len, &len, &status);

        if (res && (status == ERROR_SUCCESS)) {
            /* display the Dialog */
            res = CommConfigDialogW(pPortName, hWnd, &cfg);
            if (res) {
                status = ERROR_SUCCESS;
                /* set new settings */
                res = XcvDataW(hXcv, cmd_SetDefaultCommConfigW,
                               (PBYTE) &cfg, len,
                               (PBYTE) &dummy, 0, &len, &status);
            }
        }
        HeapFree(GetProcessHeap(), 0, shortname);
        return res;
    }
    return FALSE;
}


/*****************************************************
 *   dlg_configure_lpt [internal]
 *
 */

static BOOL dlg_configure_lpt(HANDLE hXcv, HWND hWnd)
{
    lptconfig_t data;
    BOOL  res;


    data.hXcv = hXcv;

    res = DialogBoxParamW(LOCALUI_hInstance, MAKEINTRESOURCEW(LPTCONFIG_DIALOG), hWnd,
                               dlgproc_lptconfig, (LPARAM) &data);

    TRACE("got %u with %u\n", res, GetLastError());

    if (!res) SetLastError(ERROR_CANCELLED);
    return res;
}

/******************************************************************
 *  dlg_port_already_exists [internal]
 */

static void dlg_port_already_exists(HWND hWnd, LPCWSTR portname)
{
    WCHAR res_PortW[IDS_LOCALPORT_MAXLEN];
    WCHAR res_PortExistsW[IDS_PORTEXISTS_MAXLEN];
    LPWSTR  message;
    DWORD   len;

    res_PortW[0] = '\0';
    res_PortExistsW[0] = '\0';
    LoadStringW(LOCALUI_hInstance, IDS_LOCALPORT, res_PortW, IDS_LOCALPORT_MAXLEN);
    LoadStringW(LOCALUI_hInstance, IDS_PORTEXISTS, res_PortExistsW, IDS_PORTEXISTS_MAXLEN);

    len = lstrlenW(portname) + IDS_PORTEXISTS_MAXLEN + 1;
    message = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (message) {
        message[0] = '\0';
        snprintfW(message, len, res_PortExistsW, portname);
        MessageBoxW(hWnd, message, res_PortW, MB_OK | MB_ICONERROR);
        HeapFree(GetProcessHeap(), 0, message);
    }
}

/******************************************************************
 *  dlg_invalid_portname [internal]
 */

static void dlg_invalid_portname(HWND hWnd, LPCWSTR portname)
{
    WCHAR res_PortW[IDS_LOCALPORT_MAXLEN];
    WCHAR res_InvalidNameW[IDS_INVALIDNAME_MAXLEN];
    LPWSTR  message;
    DWORD   len;

    res_PortW[0] = '\0';
    res_InvalidNameW[0] = '\0';
    LoadStringW(LOCALUI_hInstance, IDS_LOCALPORT, res_PortW, IDS_LOCALPORT_MAXLEN);
    LoadStringW(LOCALUI_hInstance, IDS_INVALIDNAME, res_InvalidNameW, IDS_INVALIDNAME_MAXLEN);

    len = lstrlenW(portname) + IDS_INVALIDNAME_MAXLEN;
    message = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (message) {
        message[0] = '\0';
        snprintfW(message, len, res_InvalidNameW, portname);
        MessageBoxW(hWnd, message, res_PortW, MB_OK | MB_ICONERROR);
        HeapFree(GetProcessHeap(), 0, message);
    }
}

/******************************************************************
 * display the Dialog "Nothing to configure"
 *
 */

static void dlg_nothingtoconfig(HWND hWnd)
{
    WCHAR res_PortW[IDS_LOCALPORT_MAXLEN];
    WCHAR res_nothingW[IDS_NOTHINGTOCONFIG_MAXLEN];

    res_PortW[0] = '\0';
    res_nothingW[0] = '\0';
    LoadStringW(LOCALUI_hInstance, IDS_LOCALPORT, res_PortW, IDS_LOCALPORT_MAXLEN);
    LoadStringW(LOCALUI_hInstance, IDS_NOTHINGTOCONFIG, res_nothingW, IDS_NOTHINGTOCONFIG_MAXLEN);

    MessageBoxW(hWnd, res_nothingW, res_PortW, MB_OK | MB_ICONINFORMATION);
}

/******************************************************************
 *  dlg_win32error [internal]
 */

static void dlg_win32error(HWND hWnd, DWORD lasterror)
{
    WCHAR res_PortW[IDS_LOCALPORT_MAXLEN];
    LPWSTR  message = NULL;
    DWORD   res;

    res_PortW[0] = '\0';
    LoadStringW(LOCALUI_hInstance, IDS_LOCALPORT, res_PortW, IDS_LOCALPORT_MAXLEN);


    res = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                        NULL, lasterror, 0, (LPWSTR) &message, 0, NULL);

    if (res > 0) {
        MessageBoxW(hWnd, message, res_PortW, MB_OK | MB_ICONERROR);
        LocalFree(message);
    }
}

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

static INT_PTR CALLBACK dlgproc_addport(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    addportui_t * data;
    DWORD   status;
    DWORD   dummy;
    DWORD   len;
    DWORD   res;

    switch(msg)
    {
    case WM_INITDIALOG:
        SetWindowLongPtrW(hwnd, DWLP_USER, lparam);
        return TRUE;

    case WM_COMMAND:
        if (wparam == MAKEWPARAM(IDOK, BN_CLICKED))
        {
            data = (addportui_t *) GetWindowLongPtrW(hwnd, DWLP_USER);
            /* length in WCHAR, without the '\0' */
            len = SendDlgItemMessageW(hwnd, ADDPORT_EDIT, WM_GETTEXTLENGTH, 0, 0);
            data->portname = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));

            if (!data->portname) {
                EndDialog(hwnd, FALSE);
                return TRUE;
            }
            /* length is in WCHAR, including the '\0' */
            GetDlgItemTextW(hwnd, ADDPORT_EDIT, data->portname, len + 1);
            status = ERROR_SUCCESS;
            res = XcvDataW( data->hXcv, cmd_PortIsValidW, (PBYTE) data->portname,
                            (lstrlenW(data->portname) + 1) * sizeof(WCHAR),
                            (PBYTE) &dummy, 0, &len, &status);

            TRACE("got %u with status %u\n", res, status);
            if (res && (status == ERROR_SUCCESS)) {
                /* The caller must free data->portname */
                EndDialog(hwnd, TRUE);
                return TRUE;
            }

            if (res && (status == ERROR_INVALID_NAME)) {
                dlg_invalid_portname(hwnd, data->portname);
                HeapFree(GetProcessHeap(), 0, data->portname);
                data->portname = NULL;
                return TRUE;
            }

            dlg_win32error(hwnd, status);
            HeapFree(GetProcessHeap(), 0, data->portname);
            data->portname = NULL;
            return TRUE;
        }

        if (wparam == MAKEWPARAM(IDCANCEL, BN_CLICKED))
        {
            EndDialog(hwnd, FALSE);
            return TRUE;
        }
        return FALSE;
    }
    return FALSE;
}

/*****************************************************************************
 *   dlgproc_lptconfig  [internal]
 *
 * Our message-proc is simple, as the range-check is done only during the
 * command "OK" and the dialog is set to the start-value at "out of range".
 *
 * Native localui.dll does the check during keyboard-input and set the dialog
 * to the previous value.
 *
 */

static INT_PTR CALLBACK dlgproc_lptconfig(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    lptconfig_t * data;
    WCHAR   bufferW[16];
    DWORD   status;
    DWORD   dummy;
    DWORD   len;
    DWORD   res;


    switch(msg)
    {
    case WM_INITDIALOG:
        SetWindowLongPtrW(hwnd, DWLP_USER, lparam);
        data = (lptconfig_t *) lparam;

        /* Get current setting */
        data->value = 45;
        status = ERROR_SUCCESS;
        res = XcvDataW( data->hXcv, cmd_GetTransmissionRetryTimeoutW,
                        (PBYTE) &dummy, 0,
                        (PBYTE) &data->value, sizeof(data->value), &len, &status);

        TRACE("got %u with status %u\n", res, status);

        /* Set current setting as the initial value in the Dialog */
        SetDlgItemInt(hwnd, LPTCONFIG_EDIT, data->value, FALSE);
        return TRUE;

    case WM_COMMAND:
        if (wparam == MAKEWPARAM(IDOK, BN_CLICKED))
        {
            data = (lptconfig_t *) GetWindowLongPtrW(hwnd, DWLP_USER);

            status = FALSE;
            res = GetDlgItemInt(hwnd, LPTCONFIG_EDIT, (BOOL *) &status, FALSE);
            /* length is in WCHAR, including the '\0' */
            GetDlgItemTextW(hwnd, LPTCONFIG_EDIT, bufferW, sizeof(bufferW) / sizeof(bufferW[0]));
            TRACE("got %s and %u (translated: %u)\n", debugstr_w(bufferW), res, status);

            /* native localui.dll use the same limits */
            if ((res > 0) && (res < 1000000) && status) {
                sprintfW(bufferW, fmt_uW, res);
                res = XcvDataW( data->hXcv, cmd_ConfigureLPTPortCommandOKW,
                        (PBYTE) bufferW,
                        (lstrlenW(bufferW) +1) * sizeof(WCHAR),
                        (PBYTE) &dummy, 0, &len, &status);

                TRACE("got %u with status %u\n", res, status);
                EndDialog(hwnd, TRUE);
                return TRUE;
            }

            /* Set initial value and rerun the Dialog */
            SetDlgItemInt(hwnd, LPTCONFIG_EDIT, data->value, FALSE);
            return TRUE;
        }

        if (wparam == MAKEWPARAM(IDCANCEL, BN_CLICKED))
        {
            EndDialog(hwnd, FALSE);
            return TRUE;
        }
        return FALSE;
    }
    return FALSE;
}


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

static DWORD get_type_from_name(LPCWSTR name)
{
    HANDLE  hfile;

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

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

    if (!strcmpiW(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;
}

/*****************************************************
 *   open_monitor_by_name [internal]
 *
 */
static BOOL open_monitor_by_name(LPCWSTR pPrefix, LPCWSTR pPort, HANDLE * phandle)
{
    PRINTER_DEFAULTSW pd;
    LPWSTR  fullname;
    BOOL    res;

    * phandle = 0;
    TRACE("(%s,%s)\n", debugstr_w(pPrefix),debugstr_w(pPort) );

    fullname = strdupWW(pPrefix, pPort);
    pd.pDatatype = NULL;
    pd.pDevMode  = NULL;
    pd.DesiredAccess = SERVER_ACCESS_ADMINISTER;

    res = OpenPrinterW(fullname, phandle, &pd);
    HeapFree(GetProcessHeap(), 0, fullname);
    return res;
}

/*****************************************************
 *   localui_AddPortUI [exported through MONITORUI]
 *
 * Display a Dialog to add a local Port
 *
 * PARAMS
 *  pName       [I] Servername or NULL (local Computer)
 *  hWnd        [I] Handle to parent Window for the Dialog-Box or NULL
 *  pMonitorName[I] Name of the Monitor, that should be used to add a Port or NULL
 *  ppPortName  [O] PTR to PTR of a buffer, that receive the Name of the new Port or NULL
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 * NOTES
 * The caller must free the buffer (returned in ppPortName) with GlobalFree().
 * Native localui.dll failed with ERROR_INVALID_PARAMETER, when the user tried
 * to add a Port, that start with "COM" or "LPT".
 *
 */
static BOOL WINAPI localui_AddPortUI(PCWSTR pName, HWND hWnd, PCWSTR pMonitorName, PWSTR *ppPortName)
{
    addportui_t data;
    HANDLE  hXcv;
    DWORD   needed;
    DWORD   dummy;
    DWORD   status;
    DWORD   res = FALSE;

    TRACE(  "(%s, %p, %s, %p) (*ppPortName: %p)\n", debugstr_w(pName), hWnd,
            debugstr_w(pMonitorName), ppPortName, ppPortName ? *ppPortName : NULL);

    if (open_monitor_by_name(XcvMonitorW, pMonitorName, &hXcv)) {

        ZeroMemory(&data, sizeof(addportui_t));
        data.hXcv = hXcv;
        res = DialogBoxParamW(LOCALUI_hInstance, MAKEINTRESOURCEW(ADDPORT_DIALOG), hWnd,
                               dlgproc_addport, (LPARAM) &data);

        TRACE("got %u with %u for %s\n", res, GetLastError(), debugstr_w(data.portname));

        if (ppPortName) *ppPortName = NULL;

        if (res) {
            res = XcvDataW(hXcv, cmd_AddPortW, (PBYTE) data.portname,
                            (lstrlenW(data.portname)+1) * sizeof(WCHAR),
                            (PBYTE) &dummy, 0, &needed, &status);

            TRACE("got %u with status %u\n", res, status);
            if (res && (status == ERROR_SUCCESS) && ppPortName) {
                /* Native localui uses GlobalAlloc also.
                   The caller must GlobalFree the buffer */
                *ppPortName = GlobalAlloc(GPTR, (lstrlenW(data.portname)+1) * sizeof(WCHAR));
                if (*ppPortName) lstrcpyW(*ppPortName, data.portname);
            }

            if (res && (status == ERROR_ALREADY_EXISTS)) {
                dlg_port_already_exists(hWnd, data.portname);
                /* Native localui also return "TRUE" from AddPortUI in this case */
            }

            HeapFree(GetProcessHeap(), 0, data.portname);
        }
        else
        {
            SetLastError(ERROR_CANCELLED);
        }
        ClosePrinter(hXcv);
    }

    TRACE("=> %u with %u\n", res, GetLastError());
    return res;
}


/*****************************************************
 *   localui_ConfigurePortUI [exported through MONITORUI]
 *
 * Display the Configuration-Dialog for a specific Port
 *
 * PARAMS
 *  pName     [I] Servername or NULL (local Computer)
 *  hWnd      [I] Handle to parent Window for the Dialog-Box or NULL
 *  pPortName [I] Name of the Port, that should be configured
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 */
static BOOL WINAPI localui_ConfigurePortUI(PCWSTR pName, HWND hWnd, PCWSTR pPortName)
{
    HANDLE  hXcv;
    DWORD   res;

    TRACE("(%s, %p, %s)\n", debugstr_w(pName), hWnd, debugstr_w(pPortName));
    if (open_monitor_by_name(XcvPortW, pPortName, &hXcv)) {

        res = get_type_from_name(pPortName);
        switch(res)
        {

        case PORT_IS_COM:
            res = dlg_configure_com(hXcv, hWnd, pPortName);
            break;

        case PORT_IS_LPT:
            res = dlg_configure_lpt(hXcv, hWnd);
            break;

        default:
            dlg_nothingtoconfig(hWnd);
            SetLastError(ERROR_CANCELLED);
            res = FALSE;
        }

        ClosePrinter(hXcv);
        return res;
    }
    return FALSE;

}

/*****************************************************
 *   localui_DeletePortUI [exported through MONITORUI]
 *
 * Delete a specific Port
 *
 * PARAMS
 *  pName     [I] Servername or NULL (local Computer)
 *  hWnd      [I] Handle to parent Window
 *  pPortName [I] Name of the Port, that should be deleted
 *
 * RETURNS
 *  Success: TRUE
 *  Failure: FALSE
 *
 * NOTES
 *  Native localui does not allow to delete a COM / LPT - Port (ERROR_NOT_SUPPORTED)
 *
 */
static BOOL WINAPI localui_DeletePortUI(PCWSTR pName, HWND hWnd, PCWSTR pPortName)
{
    HANDLE  hXcv;
    DWORD   dummy;
    DWORD   needed;
    DWORD   status;

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

    if ((!pPortName) || (!pPortName[0])) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (open_monitor_by_name(XcvPortW, pPortName, &hXcv)) {
        /* native localui tests here for LPT / COM - Ports and failed with
           ERROR_NOT_SUPPORTED. */
        if (XcvDataW(hXcv, cmd_DeletePortW, (LPBYTE) pPortName,
            (lstrlenW(pPortName)+1) * sizeof(WCHAR), (LPBYTE) &dummy, 0, &needed, &status)) {

            ClosePrinter(hXcv);
            if (status != ERROR_SUCCESS) SetLastError(status);
            return (status == ERROR_SUCCESS);
        }
        ClosePrinter(hXcv);
        return FALSE;
    }
    SetLastError(ERROR_UNKNOWN_PORT);
    return FALSE;
}

/*****************************************************
 *      InitializePrintMonitorUI  (LOCALUI.@)
 *
 * Initialize the User-Interface for the Local Ports
 *
 * RETURNS
 *  Success: Pointer to a MONITORUI Structure
 *  Failure: NULL
 *
 */

PMONITORUI WINAPI InitializePrintMonitorUI(void)
{
    static MONITORUI mymonitorui =
    {
        sizeof(MONITORUI),
        localui_AddPortUI,
        localui_ConfigurePortUI,
        localui_DeletePortUI
    };

    TRACE("=> %p\n", &mymonitorui);
    return &mymonitorui;
}

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

    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls( hinstDLL );
            LOCALUI_hInstance = hinstDLL;
            break;
    }
    return TRUE;
}
