/*
 * SetupAPI virtual copy operations
 *
 * Copyright 2001 Andreas Mohr
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * FIXME: we now rely on builtin setupapi.dll for dialog resources.
 *        This is bad ! We ought to have 16bit resource handling working.
 */

#include <string.h>
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "setupapi.h"
#include "setupx16.h"
#include "setupapi_private.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(setupapi);

/* ### start build ### */
extern WORD CALLBACK VCP_CallTo16_word_lwwll(FARPROC16,LPVOID,UINT16,WPARAM,LPARAM,LPARAM);
/* ### stop build ### */

static FARPROC16 VCP_Proc = NULL;
static LPARAM VCP_MsgRef = 0;

#define VCP_CALLBACK(obj,msg,wParam,lParam,lParamRef) \
	(VCP_Proc) ? \
	VCP_CallTo16_word_lwwll(VCP_Proc, obj,msg,wParam,lParam,lParamRef) : OK;

static BOOL VCP_opened = FALSE;

static VCPSTATUS vcp_status;

static HINSTANCE SETUPAPI_hInstance;

/****************************** VHSTR management ******************************/

/*
 * This is a totally braindead implementation for now;
 * I don't care about speed at all ! Size and implementation time
 * is much more important IMHO. I could have created some sophisticated
 * tree structure, but... what the hell ! :-)
 */
typedef struct {
    DWORD refcount;
    LPCSTR pStr;
} VHSTR_STRUCT;

static VHSTR_STRUCT **vhstrlist = NULL;
static VHSTR vhstr_alloc = 0;

#define VALID_VHSTR(x)		((x < vhstr_alloc) && (vhstrlist[x]) && (vhstrlist[x]->refcount))

/***********************************************************************
 *		vsmStringAdd (SETUPX.207)
 */
VHSTR WINAPI vsmStringAdd16(LPCSTR lpszName)
{
    VHSTR n;
    VHSTR index = 0xffff;
    HANDLE heap;

    TRACE("add string '%s'\n", lpszName);
    /* search whether string already inserted */
    TRACE("searching for existing string...\n");
    for (n = 0; n < vhstr_alloc; n++)
    {
	if ((vhstrlist[n]) && (vhstrlist[n]->refcount))
	{
		TRACE("checking item: %d\n", n);
	    if (!strcmp(vhstrlist[n]->pStr, lpszName))
	    {
		TRACE("found\n");
		vhstrlist[n]->refcount++;
		return n;
	    }
	}
    }

    /* hmm, not found yet, let's insert it */
    TRACE("inserting item\n");
    for (n = 0; n < vhstr_alloc; n++)
    {
	if ((!(vhstrlist[n])) || (!(vhstrlist[n]->refcount)))
	{
	    index = n;
	    break;
	}
    }
    heap = GetProcessHeap();
    if (n == vhstr_alloc) /* hmm, no free index found yet */
    {
	index = vhstr_alloc;
	vhstr_alloc += 20;
	vhstrlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, vhstrlist,
					sizeof(VHSTR_STRUCT *) * vhstr_alloc);
    }
    if (index == 0xffff)
	return 0xffff; /* failure */
    if (!vhstrlist[index])
	vhstrlist[index] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VHSTR_STRUCT));
    vhstrlist[index]->refcount = 1;
    vhstrlist[index]->pStr = HeapAlloc(heap, 0, strlen(lpszName)+1);
    strcpy((LPSTR)vhstrlist[index]->pStr, lpszName);
    return index;
}

/***********************************************************************
 *		vsmStringDelete (SETUPX.206)
 */
INT16 WINAPI vsmStringDelete16(VHSTR vhstr)
{
    if (VALID_VHSTR(vhstr))
    {
	vhstrlist[vhstr]->refcount--;
	if (!vhstrlist[vhstr]->refcount)
	{
	    HeapFree(GetProcessHeap(), 0, (LPSTR)vhstrlist[vhstr]->pStr);
	    vhstrlist[vhstr]->pStr = NULL;
	}
	return VCPN_OK;
    }

    /* string not found */
    return VCPN_FAIL;
}

/*
 * vsmStringFind() - not exported from a standard SETUPX.DLL, it seems
 */
VHSTR WINAPI vsmStringFind16(LPCSTR lpszName)
{
    WORD n;
    for (n = 0; n < vhstr_alloc; n++)
	if ((vhstrlist[n]) && (vhstrlist[n]->refcount) && (!strcmp(vhstrlist[n]->pStr, lpszName)))
	    return n;
    return 0xffff;
}

/***********************************************************************
 *		vsmGetStringName (SETUPX.205)
 *
 * Pretty correct, I guess
 */
INT16 WINAPI vsmGetStringName16(VHSTR vhstr, LPSTR lpszBuffer, int cbBuffer)
{
    if (VALID_VHSTR(vhstr))
    {
	int len = strlen(vhstrlist[vhstr]->pStr)+1;
	if (cbBuffer >= len)
	{
	    if (lpszBuffer)
	        strcpy(lpszBuffer, vhstrlist[vhstr]->pStr);
	    return len;
	}
    }
    return VCPN_FAIL;
}

/***********************************************************************
 *		vsmStringCompare (not exported from a standard SETUPX.DLL, it seems)
 */
INT16 WINAPI vsmStringCompare16(VHSTR vhstrA, VHSTR vhstrB)
{
    if ((!VALID_VHSTR(vhstrA)) || (!VALID_VHSTR(vhstrB)))
	return VCPN_FAIL; /* correct ? */
    return strcmp(vhstrlist[vhstrA]->pStr, vhstrlist[vhstrB]->pStr);
}

/***********************************************************************
 *		vsmGetStringRawName (SETUPX.208)
 */
LPCSTR WINAPI vsmGetStringRawName16(VHSTR vhstr)
{
    return (VALID_VHSTR(vhstr)) ? vhstrlist[vhstr]->pStr : NULL;
}


/***************************** VIRTNODE management ****************************/
static LPVIRTNODE *pvnlist = NULL;
static DWORD vn_num = 0;
static DWORD vn_last = 0;

RETERR16 VCP_VirtnodeCreate(LPVCPFILESPEC vfsSrc, LPVCPFILESPEC vfsDst, WORD fl, LPARAM lParam, LPEXPANDVTBL lpExpandVtbl)
{
    HANDLE heap;
    LPVIRTNODE lpvn;
    RETERR16 cbres;

    while (vn_last < vn_num)
    {
	if (pvnlist[vn_last] == NULL)
	    break;
	vn_last++;
    }
    heap = GetProcessHeap();
    if (vn_last == vn_num)
    {
	vn_num += 20;
        pvnlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, pvnlist,
		    		sizeof(LPVIRTNODE *) * vn_num);
    }
    pvnlist[vn_last] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VIRTNODE));
    lpvn = pvnlist[vn_last];
    vn_last++;

    lpvn->cbSize = sizeof(VIRTNODE);

    if (vfsSrc)
        memcpy(&lpvn->vfsSrc, vfsSrc, sizeof(VCPFILESPEC));

    if (vfsDst)
        memcpy(&lpvn->vfsDst, vfsDst, sizeof(VCPFILESPEC));

    lpvn->fl = fl;
    lpvn->lParam = lParam;
    lpvn->lpExpandVtbl = lpExpandVtbl;

    lpvn->vhstrDstFinalName = 0xffff; /* FIXME: what is this ? */

    cbres = VCP_CALLBACK(lpvn, VCPM_NODECREATE, 0, 0, VCP_MsgRef);
    lpvn->fl |= VFNL_CREATED;
    cbres = VCP_CALLBACK(lpvn, VCPM_NODEACCEPT, 0, 0, VCP_MsgRef);

    return OK;
}

BOOL VCP_VirtnodeDelete(LPVIRTNODE lpvnDel)
{
    DWORD n;
    RETERR16 cbres;

    for (n = 0; n < vn_last; n++)
    {
	if (pvnlist[n] == lpvnDel)
	{
	    cbres = VCP_CALLBACK(lpvnDel, VCPM_NODEDESTROY, 0, 0, VCP_MsgRef);
	    HeapFree(GetProcessHeap(), 0, lpvnDel);
	    pvnlist[n] = NULL;
	    return TRUE;
	}
    }
    return FALSE;
}

/***********************************************************************
 *		VcpOpen (SETUPX.200)
 *
 * Sets up a virtual copy operation.
 * This means that functions such as GenInstall()
 * create a VIRTNODE struct for every file to be touched in a .INF file
 * instead of actually touching the file.
 * The actual copy/move/rename gets started when VcpClose or
 * VcpFlush is called; several different callbacks are made
 * (copy, rename, open, close, version conflicts, ...) on every file copied.
 */
RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)
{
    TRACE("(%p, %08lx)\n", vifproc, lparamMsgRef);
    if (VCP_opened)
	return ERR_VCP_BUSY;

    VCP_Proc = (FARPROC16)vifproc;
    VCP_MsgRef = lparamMsgRef;

    /* load SETUPAPI needed for dialog resources etc. */
    SETUPAPI_hInstance = LoadLibraryA("setupapi.dll");
    if (!SETUPAPI_hInstance)
    {
	ERR("Could not load sibling setupapi.dll\n");
	return ERR_VCP_NOMEM;
    }
    VCP_opened = TRUE;
    return OK;
}

/***********************************************************************
 *		VcpQueueCopy		[SETUPX.13]
 *
 * lpExpandVtbl seems to be deprecated.
 * fl are the CNFL_xxx and VNFL_xxx flags.
 * lParam are the VNLP_xxx flags.
 */
RETERR16 WINAPI VcpQueueCopy16(
	LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
	LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
	LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
	LPEXPANDVTBL lpExpandVtbl,
	WORD fl, LPARAM lParam
)
{
    VCPFILESPEC vfsSrc, vfsDst;

    if (!VCP_opened)
	return ERR_VCP_NOTOPEN;

    TRACE("srcdir: %s, srcfile: %s, dstdir: %s, dstfile: %s\n",
      lpszSrcDir, lpszSrcFileName, lpszDstDir, lpszDstFileName);

    TRACE("ldidSrc == %d, ldidDst == %d\n", ldidSrc, ldidDst);

    vfsSrc.ldid = ldidSrc;
    vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
    vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);

    vfsDst.ldid = ldidDst;
    vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
    vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);

    return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, fl, lParam,
		    lpExpandVtbl);
}

/***********************************************************************
 *		VcpQueueDelete		[SETUPX.17]
 *
 * Is lParamRef the same as lParam in VcpQueueCopy ?
 * Damn docu !! Err... which docu ?
 */
RETERR16 WINAPI VcpQueueDelete16(
	LPCSTR lpszDstFileName,
	LPCSTR lpszDstDir,
	LOGDISKID16 ldidDst,
	LPARAM lParamRef
)
{
    VCPFILESPEC vfsDst;

    if (!VCP_opened)
	return ERR_VCP_NOTOPEN;

    vfsDst.ldid = ldidDst;
    vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
    vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);

    return VCP_VirtnodeCreate(NULL, &vfsDst, VNFL_DELETE, lParamRef, 0);
}

/***********************************************************************
 *		VcpQueueRename		[SETUPX.204]
 *
 */
RETERR16 WINAPI VcpQueueRename16(
	LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
	LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
	LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
	LPARAM lParam
)
{
    VCPFILESPEC vfsSrc, vfsDst;

    if (!VCP_opened)
	return ERR_VCP_NOTOPEN;

    vfsSrc.ldid = ldidSrc;
    vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
    vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);

    vfsDst.ldid = ldidDst;
    vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
    vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);

    return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, VNFL_RENAME, lParam,
		    0);
}

/***********************************************************************
 *		VcpEnumFiles (SETUPX.@)
 */
INT16 WINAPI VcpEnumFiles(VCPENUMPROC vep, LPARAM lParamRef)
{
    WORD n;

    for (n = 0; n < vn_last; n++)
	vep(pvnlist[n], lParamRef);

    return 0; /* FIXME: return value ? */
}

/***********************************************************************
 *		VcpExplain (SETUPX.411)
 */
LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat)
{
    static char buffer[MAX_PATH]; /* FIXME: is this how it's done ? */
    buffer[0] = '\0';
    switch (dwWhat)
    {
	case VCPEX_SRC_FULL:
	case VCPEX_DST_FULL:
	    {
		LPVCPFILESPEC lpvfs =
		    (dwWhat == VCPEX_SRC_FULL) ?  &lpVn->vfsSrc : &lpVn->vfsDst;

                /* if we have an ldid, use it, otherwise use the string */
                /* from the vhstrlist array */
		if (lpvfs->ldid != 0xffff)
                  CtlGetLddPath16(lpvfs->ldid, buffer);
                else
                  strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrDir));

                strcat(buffer, "\\");
                strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrFileName));
	    }
	    break;
	default:
	    FIXME("%ld unimplemented !\n", dwWhat);
	    strcpy(buffer, "Unknown error");
	    break;
    }
    return buffer;
}

RETERR16 VCP_CheckPaths(void)
{
    DWORD n;
    LPVIRTNODE lpvn;
    RETERR16 cbres;

    cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATPATHCHECKSTART, 0, 0, VCP_MsgRef);
    for (n = 0; n < vn_num; n++)
    {
	lpvn = pvnlist[n];
	if (!lpvn) continue;
        /* FIXME: check paths of all VIRTNODEs here ! */
	cbres = VCP_CALLBACK(&lpvn->vfsDst, VCPM_CHECKPATH, 0, (DWORD)lpvn, VCP_MsgRef);
    }
    cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATPATHCHECKEND, 0, 0, VCP_MsgRef);
    return OK;
}

RETERR16 VCP_CopyFiles(void)
{
    char fn_src[MAX_PATH], fn_dst[MAX_PATH];
    RETERR16 res = OK, cbres;
    DWORD n;
    LPVIRTNODE lpvn;

    cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCOPYSTART, 0, 0, VCP_MsgRef);
    for (n = 0; n < vn_num; n++)
    {
	lpvn = pvnlist[n];
	if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_COPY)) continue;
	/* FIXME: need to send VCPM_VSTATNEWDISK notification sometimes */
        strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
        strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
	/* FIXME: what is this VCPM_VSTATWRITE here for ?
	 * I guess it's to signal successful destination file creation */
	cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);

	/* FIXME: need to do the file copy in small chunks for notifications */
	TRACE("copying '%s' to '%s'\n", fn_src, fn_dst);
        /* perform the file copy */
        if (!(CopyFileA(fn_src, fn_dst, TRUE)))
        {
            ERR("error copying, src: %s -> dst: %s\n", fn_src, fn_dst);
	    res = ERR_VCP_IOFAIL;
        }

	vcp_status.prgFileRead.dwSoFar++;
	cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATREAD, 0, 0, VCP_MsgRef);
	vcp_status.prgFileWrite.dwSoFar++;
	cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
    }

    cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCOPYEND, 0, 0, VCP_MsgRef);
    return res;
}

/***********************************************************************
 *		VcpFlush - internal (not exported), but documented
 *
 * VNFL_NOW is used for VcpFlush.
 */
RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest)
{
    return OK;
}

/***********************************************************************
 *		VcpClose (SETUPX.201)
 *
 * Does callbacks (-> vifproc) with VCPM_VSTATCLOSESTART,
 * VCPM_VSTATCLOSEEND.
 *
 * fl gets VCPFL_xxx flags to indicate what to do with the
 * VIRTNODEs (files to mess with) created by e.g. GenInstall()
 */
RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)
{
    RETERR16 res = OK;
    WORD cbres = VCPN_PROCEED;

    TRACE("(%04x, '%s')\n", fl, lpszBackupDest);

    /* FIXME: needs to sort virtnodes in case VCPFL_INSPECIFIEDORDER
     * is not set. This is done by VCP_CALLBACK(VCPM_NODECOMPARE) */

    TRACE("#1\n");
    memset(&vcp_status, 0, sizeof(VCPSTATUS));
    /* yes, vcp_status.cbSize is 0 ! */
    TRACE("#2\n");
    cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCLOSESTART, 0, 0, VCP_MsgRef);
    TRACE("#3\n");

    res = VCP_CheckPaths();
    TRACE("#4\n");
    if (res != OK)
	return res; /* is this ok ? */
    VCP_CopyFiles();

    TRACE("#5\n");
    cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCLOSEEND, 0, 0, VCP_MsgRef);
    TRACE("#6\n");
    VCP_Proc = NULL;
    FreeLibrary(SETUPAPI_hInstance);
    VCP_opened = FALSE;
    return OK;
}

RETERR16 VCP_RenameFiles(void)
{
    char fn_src[MAX_PATH], fn_dst[MAX_PATH];
    RETERR16 res = OK, cbres;
    DWORD n;
    LPVIRTNODE lpvn;

    cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATRENAMESTART, 0, 0, VCP_MsgRef);
    for (n = 0; n < vn_num; n++)
    {
	lpvn = pvnlist[n];
	if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_RENAME)) continue;
        strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
        strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
	cbres = VCP_CALLBACK(&lpvn->vfsDst, VCPM_FILEOPENOUT, 0, (LPARAM)lpvn, VCP_MsgRef);
        if (!(MoveFileExA(fn_src, fn_dst, MOVEFILE_REPLACE_EXISTING)))
	    res = ERR_VCP_IOFAIL;
	else
	    VCP_VirtnodeDelete(lpvn);
    }
    cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATRENAMEEND, 0, 0, VCP_MsgRef);
    return res;
}

/***********************************************************************
 *		vcpDefCallbackProc (SETUPX.202)
 */
RETERR16 WINAPI vcpDefCallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
					LPARAM lParam, LPARAM lParamRef)
{
    static int count = 0;
    if (count < 10)
        FIXME("(%p, %04x, %04x, %08lx, %08lx) - what to do here ?\n",
		lpvObj, uMsg, wParam, lParam, lParamRef);
    count++;
    return OK;
}

/********************* point-and-click stuff from here ***********************/

static HWND hDlgCopy = 0;
static HKEY hKeyFiles = 0, hKeyRename = 0, hKeyConflict = 0;
static char BackupDir[12];

static BOOL CALLBACK VCP_UI_FileCopyDlgProc(HWND hWndDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    BOOL retval = FALSE;

    if (iMsg == WM_INITDIALOG)
    {
        ShowWindow(hWndDlg, SW_SHOWNORMAL);
        UpdateWindow(hWndDlg);
	retval = TRUE;
    }
    return retval;
}

BOOL VCP_UI_GetDialogTemplate(LPCVOID *template32)
{
    HANDLE hResInfo, hDlgTmpl32;

    if (!(hResInfo = FindResourceA(SETUPAPI_hInstance, MAKEINTRESOURCEA(COPYFILEDLGORD), RT_DIALOGA)))
	return FALSE;
    if (!(hDlgTmpl32 = LoadResource(SETUPAPI_hInstance, hResInfo )) ||
        !(*template32 = LockResource( hDlgTmpl32 )))
	return FALSE;
    return TRUE;
}

static LRESULT WINAPI
VCP_UI_FileCopyWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg != WM_CREATE)
        return DefWindowProcA (hwnd, uMsg, wParam, lParam);

    switch (uMsg)
    {
	case WM_CREATE:
	    return 0;
	default:
	    FIXME("%04x: unhandled.\n", uMsg);
    }

    return 0;
}

void VCP_UI_RegisterProgressClass(void)
{
    static BOOL registered = FALSE;
    WNDCLASSA wndClass;

    if (registered)
	return;

    registered = TRUE;
    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc   = (WNDPROC)VCP_UI_FileCopyWndProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = 0;
    wndClass.hCursor       = LoadCursorA (0, IDC_ARROWA);
    wndClass.hbrBackground = (HBRUSH)NULL;
    wndClass.lpszClassName = "setupx_progress";

    RegisterClassA (&wndClass);
}

RETERR16 VCP_UI_NodeCompare(LPVIRTNODE vn1, LPVIRTNODE vn2)
{
    LPCSTR file1, file2;
    file1 = vsmGetStringRawName16(vn1->vfsSrc.vhstrFileName);
    file2 = vsmGetStringRawName16(vn2->vfsSrc.vhstrFileName);
    return (RETERR16)strcmp(file1, file2);
}

RETERR16 VCP_UI_CopyStart(void)
{
    LPCVOID template32;
    char buf[256]; /* plenty */
    BOOL dirty;
    DWORD len;

    /* FIXME: should be registered at DLL startup instead */
    VCP_UI_RegisterProgressClass();
    if (!(VCP_UI_GetDialogTemplate(&template32)))
	return VCPN_FAIL;

    if (vn_num > 10)  /* hack */
    {
        hDlgCopy = CreateDialogIndirectParamA(SETUPAPI_hInstance, template32, 0,
                                              VCP_UI_FileCopyDlgProc, 0);
        if (!hDlgCopy)
            return VCPN_FAIL;
        SetDlgItemTextA(hDlgCopy, SOURCESTRORD, "Scanning ...");
        SetDlgItemTextA(hDlgCopy, DESTSTRORD, "NOT_IMPLEMENTED_YET");
    }
    strcpy(buf, REG_INSTALLEDFILES);
    if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyFiles))
	return VCPN_FAIL;
    strcat(buf, REGPART_RENAME);
    if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyRename))
	return VCPN_FAIL;
    if (RegCreateKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT, &hKeyConflict))
	return VCPN_FAIL;
    len = 1;
    if (!(RegQueryValueExA(hKeyConflict, "Dirty", NULL, 0, (LPBYTE)&dirty, &len)))
    {
	/* FIXME: what does SETUPX.DLL do in this case ? */
	MESSAGE("Warning: another program using SETUPX is already running ! Failed.\n");
	return VCPN_FAIL;
    }
    dirty = TRUE;
    if (RegSetValueExA(hKeyConflict, "Dirty", 0, REG_BINARY, (LPBYTE)&dirty, 1))
	return VCPN_FAIL;
    len = 12;
    if (!(RegQueryValueExA(hKeyConflict, "BackupDirectory", NULL, 0, BackupDir, &len)))
	strcpy(BackupDir, "VCM");

    /* create C:\WINDOWS\[BackupDir] and set registry key to it */
    GetWindowsDirectoryA(buf, 256);
    strcat(buf, "\\");
    strcat(buf, BackupDir);
    if (!(CreateDirectoryA(buf, NULL)))
	return VCPN_FAIL;
    if (RegSetValueExA(hKeyConflict, "BackupDirectory", 0, REG_SZ, (LPBYTE)buf, strlen(buf)+1))
	return VCPN_FAIL;
    RegCloseKey(hKeyConflict);

    return VCPN_OK;
}

/***********************************************************************
 *		vcpUICallbackProc (SETUPX.213)
 */
RETERR16 WINAPI vcpUICallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
					LPARAM lParam, LPARAM lParamRef)
{
    static int count = 0;
    RETERR16 res = VCPN_OK, cbres;

    if (count < 5)
        FIXME("(%p, %04x, %04x, %08lx, %08lx) - semi-stub\n",
		lpvObj, uMsg, wParam, lParam, lParamRef);
    count++;
    switch (uMsg)
    {
	/* unused messages, it seems */
	case VCPM_DISKPREPINFO:

	case VCPM_FILENEEDED:

	case VCPM_NODECREATE:
	case VCPM_NODEACCEPT:

	case VCPM_VSTATCLOSESTART:
	case VCPM_VSTATPATHCHECKSTART:
	case VCPM_VSTATPATHCHECKEND:

	case VCPM_CHECKPATH:
	    break;

	/* the real stuff */
	case VCPM_NODECOMPARE:
	    res = VCP_UI_NodeCompare((LPVIRTNODE)lpvObj, (LPVIRTNODE)lParam);
	    break;
	case VCPM_VSTATREAD:
	    break;
	case VCPM_VSTATWRITE:
	    cbres = VCP_CALLBACK(&vcp_status, VCPM_DISKPREPINFO, 0, 0, VCP_MsgRef);
	    break;
	case VCPM_VSTATCLOSEEND:
	    RegCloseKey(hKeyFiles);
	    RegCloseKey(hKeyRename);
	    RegDeleteKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT);
	    break;
	case VCPM_VSTATCOPYSTART:
	    res = VCP_UI_CopyStart();
	    break;
	case VCPM_VSTATCOPYEND:
	    if (hDlgCopy) DestroyWindow(hDlgCopy);
	    break;
	default:
	    FIXME("unhandled msg 0x%04x\n", uMsg);
    }
    return res;
}
