/*
 *      SETUPX library
 *
 *      Copyright 1998,2000  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: Rather non-functional functions for now.
 *
 * See:
 * http://www.geocities.com/SiliconValley/Network/5317/drivers.html
 * http://willemer.de/informatik/windows/inf_info.htm (German)
 * http://www.microsoft.com/ddk/ddkdocs/win98ddk/devinst_12uw.htm
 * DDK: setupx.h
 * http://mmatrix.tripod.com/customsystemfolder/infsysntaxfull.html
 * http://www.rdrop.com/~cary/html/inf_faq.html
 * http://support.microsoft.com/support/kb/articles/q194/6/40.asp
 *
 * Stuff tested with:
 * - rs405deu.exe (German Acroread 4.05 setup)
 * - ie5setup.exe
 * - Netmeeting
 *
 * FIXME:
 * - string handling is... weird ;) (buflen etc.)
 * - memory leaks ?
 * - separate that mess (but probably only when it's done completely)
 *
 * SETUPX consists of several parts with the following acronyms/prefixes:
 * Di	device installer (devinst.c ?)
 * Gen	generic installer (geninst.c ?)
 * Ip	.INF parsing (infparse.c)
 * LDD	logical device descriptor (ldd.c ?)
 * LDID	logical device ID
 * SU   setup (setup.c ?)
 * Tp	text processing (textproc.c ?)
 * Vcp	virtual copy module (vcp.c ?)
 * ...
 *
 * The SETUPX DLL is NOT thread-safe. That's why many installers urge you to
 * "close all open applications".
 * All in all the design of it seems to be a bit weak.
 * Not sure whether my implementation of it is better, though ;-)
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "winreg.h"
#include "wine/winuser16.h"
#include "setupx16.h"
#include "setupapi_private.h"
#include "winerror.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(setupapi);

/***********************************************************************
 *		SURegOpenKey (SETUPX.47)
 */
DWORD WINAPI SURegOpenKey( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey )
{
    FIXME("(%x,%s,%p), semi-stub.\n",hkey,debugstr_a(lpszSubKey),retkey);
    return RegOpenKeyA( hkey, lpszSubKey, retkey );
}

/***********************************************************************
 *		SURegQueryValueEx (SETUPX.50)
 */
DWORD WINAPI SURegQueryValueEx( HKEY hkey, LPSTR lpszValueName,
                                LPDWORD lpdwReserved, LPDWORD lpdwType,
                                LPBYTE lpbData, LPDWORD lpcbData )
{
    FIXME("(%x,%s,%p,%p,%p,%ld), semi-stub.\n",hkey,debugstr_a(lpszValueName),
          lpdwReserved,lpdwType,lpbData,lpcbData?*lpcbData:0);
    return RegQueryValueExA( hkey, lpszValueName, lpdwReserved, lpdwType,
                               lpbData, lpcbData );
}

/*
 * Returns pointer to a string list with the first entry being number
 * of strings.
 *
 * Hmm. Should this be InitSubstrData(), GetFirstSubstr() and GetNextSubstr()
 * instead?
 */
static LPSTR *SETUPX_GetSubStrings(LPSTR start, char delimiter)
{
    LPSTR p, q;
    LPSTR *res = NULL;
    DWORD count = 0;
    int len;

    p = start;

    while (1)
    {
	/* find beginning of real substring */
	while ( (*p == ' ') || (*p == '\t') || (*p == '"') ) p++;

	/* find end of real substring */
	q = p;
	while ( (*q)
	     &&	(*q != ' ') && (*q != '\t') && (*q != '"')
	     && (*q != ';') && (*q != delimiter) ) q++;
	if (q == p)
	    break;
	len = (int)q - (int)p;

	/* alloc entry for new substring in steps of 32 units and copy over */
	if (count % 32 == 0)
	{ /* 1 for count field + current count + 32 */
	    res = HeapReAlloc(GetProcessHeap(), 0, res, (1+count+32)*sizeof(LPSTR));
	}
	*(res+1+count) = HeapAlloc(GetProcessHeap(), 0, len+1);
	strncpy(*(res+1+count), p, len);
	(*(res+1+count))[len] = '\0';
	count++;

	/* we are still within last substring (before delimiter),
	 * so get out of it */
	while ((*q) && (*q != ';') && (*q != delimiter)) q++;
	if ((!*q) || (*q == ';'))
	    break;
	p = q+1;
    }

    /* put number of entries at beginning of list */
    *(DWORD *)res = count;
    return res;
}

static void SETUPX_FreeSubStrings(LPSTR *substr)
{
    DWORD count = *(DWORD *)substr;
    LPSTR *pStrings = substr+1;
    DWORD n;

    for (n=0; n < count; n++)
	HeapFree(GetProcessHeap(), 0, *pStrings++);

    HeapFree(GetProcessHeap(), 0, substr);
}

static void SETUPX_IsolateSubString(LPSTR *begin, LPSTR *end)
{
    LPSTR p, q;

    p = *begin;
    q = *end;

    while ((p < q) && ((*p == ' ') || (*p == '\t'))) p++;
    while ((p < q) && (*p == '"')) p++;

    while ((q-1 >= p) && ((*(q-1) == ' ') || (*(q-1) == '\t'))) q--;
    while ((q-1 >= p) && (*(q-1) == '"')) q--;

    *begin = p;
    *end = q;
}

/*
 * Example: HKLM,"Software\Microsoft\Windows\CurrentVersion","ProgramFilesDir",,"C:\"
 * FIXME: use SETUPX_GetSubStrings() instead.
 *        Hmm, but on the other hand SETUPX_GetSubStrings() will probably
 *        soon be replaced by InitSubstrData() etc. anyway.
 *
 */
static BOOL SETUPX_LookupRegistryString(LPSTR regstr, LPSTR buffer, DWORD buflen)
{
    HANDLE heap = GetProcessHeap();
    LPSTR items[5];
    LPSTR p, q, next;
    int len, n;
    HKEY hkey, hsubkey;
    DWORD dwType;

    TRACE("retrieving '%s'\n", regstr);

    p = regstr;

    /* isolate root key, subkey, value, flag, defval */
    for (n=0; n < 5; n++)
    {
	q = strchr(p, ',');
	if (!q)
	{
	    if (n == 4)
		q = p+strlen(p);
	    else
		return FALSE;
	}
	next = q+1;
	if (q < regstr)
            return FALSE;
        SETUPX_IsolateSubString(&p, &q);
        len = (int)q - (int)p;
        items[n] = HeapAlloc(heap, 0, len+1);
        strncpy(items[n], p, len);
        items[n][len] = '\0';
	p = next;
    }
    TRACE("got '%s','%s','%s','%s','%s'\n",
			items[0], items[1], items[2], items[3], items[4]);

    /* check root key */
    if (!strcasecmp(items[0], "HKCR"))
	hkey = HKEY_CLASSES_ROOT;
    else
    if (!strcasecmp(items[0], "HKCU"))
	hkey = HKEY_CURRENT_USER;
    else
    if (!strcasecmp(items[0], "HKLM"))
	hkey = HKEY_LOCAL_MACHINE;
    else
    if (!strcasecmp(items[0], "HKU"))
	hkey = HKEY_USERS;
    else
    { /* HKR ? -> relative to key passed to GenInstallEx */
	FIXME("unsupported regkey '%s'\n", items[0]);
        goto regfailed;
    }

    if (RegOpenKeyA(hkey, items[1], &hsubkey) != ERROR_SUCCESS)
        goto regfailed;

    if (RegQueryValueExA(hsubkey, items[2], NULL, &dwType, buffer, &buflen)
		!= ERROR_SUCCESS)
        goto regfailed;
    goto done;

regfailed:
    if (buffer) strcpy(buffer, items[4]); /* I don't care about buflen */
done:
    for (n=0; n < 5; n++)
        HeapFree(heap, 0, items[n]);
    if (buffer)
	TRACE("return '%s'\n", buffer);
    return TRUE;
}

static LPSTR SETUPX_GetSections(LPCSTR filename)
{
    LPSTR buf = NULL;
    DWORD len = 1024, res;

    do {
	buf = HeapReAlloc(GetProcessHeap(), 0, buf, len);
	res = GetPrivateProfileStringA(NULL, NULL, NULL, buf, len, filename);
	len *= 2;
    } while ((!res) && (len < 1048576));
    if (!res)
    {
	HeapFree(GetProcessHeap(), 0, buf);
	return NULL;
    }
    return buf;
}

static LPSTR SETUPX_GetSectionEntries(LPCSTR filename, LPCSTR section)
{
    LPSTR buf = NULL;
    DWORD len = 1024, res;

    do {
	buf = HeapReAlloc(GetProcessHeap(), 0, buf, len);
	res = GetPrivateProfileSectionA(section, buf, len, filename);
	len *= 2;
    } while ((!res) && (len < 1048576));
    if (!res)
    {
	HeapFree(GetProcessHeap(), 0, buf);
	return NULL;
    }
    return buf;
}


/***********************************************************************
 *		InstallHinfSection (SETUPX.527)
 *
 * hwnd = parent window
 * hinst = instance of SETUPX.DLL
 * lpszCmdLine = e.g. "DefaultInstall 132 C:\MYINSTALL\MYDEV.INF"
 * Here "DefaultInstall" is the .inf file section to be installed (optional).
 * The 132 value is made of the HOW_xxx flags and sometimes 128 (-> setupx16.h).
 *
 * nCmdShow = nCmdShow of CreateProcess
 */
RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lpszCmdLine, INT16 nCmdShow)
{
    LPSTR *pSub;
    DWORD count;
    HINF16 hInf = 0;
    RETERR16 res = OK, tmp;
    WORD wFlags;
    BOOL reboot = FALSE;

    TRACE("(%04x, %04x, %s, %d);\n", hwnd, hinst, lpszCmdLine, nCmdShow);

    pSub = SETUPX_GetSubStrings((LPSTR)lpszCmdLine, ' ');

    count = *(DWORD *)pSub;
    if (count < 2) /* invalid number of arguments ? */
	goto end;
    if (IpOpen16(*(pSub+count), &hInf) != OK)
    {
	res = ERROR_FILE_NOT_FOUND; /* yes, correct */
	goto end;
    }
    if (VcpOpen16(NULL, 0))
	goto end;
    if (GenInstall16(hInf, *(pSub+count-2), GENINSTALL_DO_ALL) != OK)
	goto end;
    wFlags = atoi(*(pSub+count-1)) & ~128;
    switch (wFlags)
    {
	case HOW_ALWAYS_SILENT_REBOOT:
	case HOW_SILENT_REBOOT:
	    reboot = TRUE;
	    break;
	case HOW_ALWAYS_PROMPT_REBOOT:
	case HOW_PROMPT_REBOOT:
            if (MessageBoxA(hwnd, "You must restart Wine before the new settings will take effect.\n\nDo you want to exit Wine now ?", "Systems Settings Change", MB_YESNO|MB_ICONQUESTION) == IDYES)
                reboot = TRUE;
	    break;
	default:
	    ERR("invalid flags %d !\n", wFlags);
	    goto end;
    }

    res = OK;
end:
    tmp = VcpClose16(VCPFL_ALL, NULL);
    if (tmp != OK)
	res = tmp;
    tmp = IpClose16(hInf);
    if (tmp != OK)
	res = tmp;
    SETUPX_FreeSubStrings(pSub);
    if (reboot)
    {
	/* FIXME: we should have a means of terminating all wine + wineserver */
	MESSAGE("Program or user told me to restart. Exiting Wine...\n");
	ExitProcess(1);
    }

    return res;
}

typedef struct
{
    LPCSTR RegValName;
    LPCSTR StdString; /* fallback string; sub dir of windows directory */
} LDID_DATA;

static const LDID_DATA LDID_Data[34] =
{
    { /* 0 (LDID_NULL) -- not defined */
	NULL,
	NULL
    },
    { /* 1 (LDID_SRCPATH) = source of installation. hmm, what to do here ? */
	"SourcePath", /* hmm, does SETUPX have to care about updating it ?? */
	NULL
    },
    { /* 2 (LDID_SETUPTEMP) = setup temp dir */
	"SetupTempDir",
	NULL
    },
    { /* 3 (LDID_UNINSTALL) = uninstall backup dir */
	"UninstallDir",
	NULL
    },
    { /* 4 (LDID_BACKUP) = backup dir */
	"BackupDir",
	NULL
    },
    { /* 5 (LDID_SETUPSCRATCH) = setup scratch dir */
	"SetupScratchDir",
	NULL
    },
    { /* 6 -- not defined */
	NULL,
	NULL
    },
    { /* 7 -- not defined */
	NULL,
	NULL
    },
    { /* 8 -- not defined */
	NULL,
	NULL
    },
    { /* 9 -- not defined */
	NULL,
	NULL
    },
    { /* 10 (LDID_WIN) = windows dir */
	"WinDir",
        ""
    },
    { /* 11 (LDID_SYS) = system dir */
	"SysDir",
	NULL /* call GetSystemDirectory() instead */
    },
    { /* 12 (LDID_IOS) = IOSubSys dir */
        NULL, /* FIXME: registry string ? */
	"SYSTEM\\IOSUBSYS"
    },
    { /* 13 (LDID_CMD) = COMMAND dir */
	NULL, /* FIXME: registry string ? */
	"COMMAND"
    },
    { /* 14 (LDID_CPL) = control panel dir */
	NULL,
	""
    },
    { /* 15 (LDID_PRINT) = windows printer dir */
	NULL,
	"SYSTEM" /* correct ?? */
    },
    { /* 16 (LDID_MAIL) = destination mail dir */
	NULL,
	""
    },
    { /* 17 (LDID_INF) = INF dir */
	"SetupScratchDir", /* correct ? */
	"INF"
    },
    { /* 18 (LDID_HELP) = HELP dir */
	NULL, /* ??? */
	"HELP"
    },
    { /* 19 (LDID_WINADMIN) = Admin dir */
	"WinAdminDir",
	""
    },
    { /* 20 (LDID_FONTS) = Fonts dir */
	NULL, /* ??? */
	"FONTS"
    },
    { /* 21 (LDID_VIEWERS) = Viewers */
	NULL, /* ??? */
	"SYSTEM\\VIEWERS"
    },
    { /* 22 (LDID_VMM32) = VMM32 dir */
	NULL, /* ??? */
	"SYSTEM\\VMM32"
    },
    { /* 23 (LDID_COLOR) = ICM dir */
	"ICMPath",
	"SYSTEM\\COLOR"
    },
    { /* 24 (LDID_APPS) = root of boot drive ? */
	"AppsDir",
	"C:\\"
    },
    { /* 25 (LDID_SHARED) = shared dir */
	"SharedDir",
	""
    },
    { /* 26 (LDID_WINBOOT) = Windows boot dir */
	"WinBootDir",
	""
    },
    { /* 27 (LDID_MACHINE) = machine specific files */
	"MachineDir",
	NULL
    },
    { /* 28 (LDID_HOST_WINBOOT) = Host Windows boot dir */
	"HostWinBootDir",
	NULL
    },
    { /* 29 -- not defined */
	NULL,
	NULL
    },
    { /* 30 (LDID_BOOT) = Root of boot drive */
	"BootDir",
	NULL
    },
    { /* 31 (LDID_BOOT_HOST) = Root of boot drive host */
	"BootHost",
	NULL
    },
    { /* 32 (LDID_OLD_WINBOOT) = subdir of root */
	"OldWinBootDir",
	NULL
    },
    { /* 33 (LDID_OLD_WIN) = old win dir */
	"OldWinDir",
	NULL
    }
    /* the rest (34-38) isn't too interesting, so I'll forget about it */
};

/*
 * LDD  == Logical Device Descriptor
 * LDID == Logical Device ID
 *
 * The whole LDD/LDID business might go into a separate file named
 * ldd.c.
 * At the moment I don't know what the hell these functions are really doing.
 * That's why I added reporting stubs.
 * The only thing I do know is that I need them for the LDD/LDID infrastructure.
 * That's why I implemented them in a way that's suitable for my purpose.
 */
static LDD_LIST *pFirstLDD = NULL;

static BOOL std_LDDs_done = FALSE;

void SETUPX_CreateStandardLDDs(void)
{
    HKEY hKey = 0;
    WORD n;
    DWORD type, len;
    LOGDISKDESC_S ldd;
    char buffer[MAX_PATH];

    /* has to be here, otherwise loop */
    std_LDDs_done = TRUE;

    RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", &hKey);

    for (n=0; n < sizeof(LDID_Data)/sizeof(LDID_DATA); n++)
    {
	buffer[0] = '\0';

	len = MAX_PATH;
	if ( (hKey) && (LDID_Data[n].RegValName)
	&&   (RegQueryValueExA(hKey, LDID_Data[n].RegValName,
		NULL, &type, buffer, &len) == ERROR_SUCCESS)
	&&   (type == REG_SZ) )
	{
	    TRACE("found value '%s' for LDID %d\n", buffer, n);
	}
	else
        switch(n)
	{
	    case LDID_SRCPATH:
		FIXME("LDID_SRCPATH: what exactly do we have to do here ?\n");
		strcpy(buffer, "X:\\FIXME");
		break;
	    case LDID_SYS:
	        GetSystemDirectoryA(buffer, MAX_PATH);
		break;
	    case LDID_APPS:
	    case LDID_MACHINE:
	    case LDID_HOST_WINBOOT:
	    case LDID_BOOT:
	    case LDID_BOOT_HOST:
		strcpy(buffer, "C:\\");
		break;
	    default:
		if (LDID_Data[n].StdString)
		{
		    DWORD len = GetWindowsDirectoryA(buffer, MAX_PATH);
		    LPSTR p;
		    p = buffer + len;
		    *p++ = '\\';
		    strcpy(p, LDID_Data[n].StdString);
		}
		break;
        }
	if (buffer[0])
	{
	    INIT_LDD(ldd, n);
	    ldd.pszPath = buffer;
	    TRACE("LDID %d -> '%s'\n", ldd.ldid, ldd.pszPath);
	    CtlSetLdd16(&ldd);
	}
    }
    if (hKey) RegCloseKey(hKey);
}

/***********************************************************************
 * CtlDelLdd		(SETUPX.37)
 *
 * RETURN
 *   ERR_VCP_LDDINVALID if ldid < LDID_ASSIGN_START.
 */
RETERR16 SETUPX_DelLdd(LOGDISKID16 ldid)
{
    LDD_LIST *pCurr, *pPrev = NULL;

    TRACE("(%d)\n", ldid);

    if (!std_LDDs_done)
	SETUPX_CreateStandardLDDs();

    if (ldid < LDID_ASSIGN_START)
	return ERR_VCP_LDDINVALID;

    pCurr = pFirstLDD;
    /* search until we find the appropriate LDD or hit the end */
    while ((pCurr != NULL) && (ldid > pCurr->pldd->ldid))
    {
	 pPrev = pCurr;
	 pCurr = pCurr->next;
    }
    if ( (pCurr == NULL) /* hit end of list */
      || (ldid != pCurr->pldd->ldid) )
	return ERR_VCP_LDDFIND; /* correct ? */

    /* ok, found our victim: eliminate it */

    if (pPrev)
	pPrev->next = pCurr->next;

    if (pCurr == pFirstLDD)
	pFirstLDD = NULL;
    HeapFree(GetProcessHeap(), 0, pCurr);

    return OK;
}

/***********************************************************************
 *		CtlDelLdd (SETUPX.37)
 */
RETERR16 WINAPI CtlDelLdd16(LOGDISKID16 ldid)
{
    FIXME("(%d); - please report to a.mohr@mailto.de !!!\n", ldid);
    return SETUPX_DelLdd(ldid);
}

/***********************************************************************
 * CtlFindLdd		(SETUPX.35)
 *
 * doesn't check pldd ptr validity: crash (W98SE)
 *
 * RETURN
 *   ERR_VCP_LDDINVALID if pldd->cbSize != structsize
 *   1 in all other cases ??
 *
 */
RETERR16 WINAPI CtlFindLdd16(LPLOGDISKDESC pldd)
{
    LDD_LIST *pCurr, *pPrev = NULL;

    TRACE("(%p)\n", pldd);

    if (!std_LDDs_done)
	SETUPX_CreateStandardLDDs();

    if (pldd->cbSize != sizeof(LOGDISKDESC_S))
        return ERR_VCP_LDDINVALID;

    pCurr = pFirstLDD;
    /* search until we find the appropriate LDD or hit the end */
    while ((pCurr != NULL) && (pldd->ldid > pCurr->pldd->ldid))
    {
	pPrev = pCurr;
	pCurr = pCurr->next;
    }
    if ( (pCurr == NULL) /* hit end of list */
      || (pldd->ldid != pCurr->pldd->ldid) )
	return ERR_VCP_LDDFIND; /* correct ? */

    memcpy(pldd, pCurr->pldd, pldd->cbSize);
    /* hmm, we probably ought to strcpy() the string ptrs here */

    return 1; /* what is this ?? */
}

/***********************************************************************
 * CtlSetLdd			(SETUPX.33)
 *
 * Set an LDD entry.
 *
 * RETURN
 *   ERR_VCP_LDDINVALID if pldd.cbSize != sizeof(LOGDISKDESC_S)
 *
 */
RETERR16 WINAPI CtlSetLdd16(LPLOGDISKDESC pldd)
{
    LDD_LIST *pCurr, *pPrev = NULL;
    LPLOGDISKDESC pCurrLDD;
    HANDLE heap;
    BOOL is_new = FALSE;

    TRACE("(%p)\n", pldd);

    if (!std_LDDs_done)
	SETUPX_CreateStandardLDDs();

    if (pldd->cbSize != sizeof(LOGDISKDESC_S))
	return ERR_VCP_LDDINVALID;

    heap = GetProcessHeap();
    pCurr = pFirstLDD;
    /* search until we find the appropriate LDD or hit the end */
    while ((pCurr != NULL) && (pldd->ldid > pCurr->pldd->ldid))
    {
	 pPrev = pCurr;
	 pCurr = pCurr->next;
    }
    if (pCurr == NULL) /* hit end of list */
    {
	is_new = TRUE;
        pCurr = HeapAlloc(heap, 0, sizeof(LDD_LIST));
        pCurr->pldd = HeapAlloc(heap, 0, sizeof(LOGDISKDESC_S));
        pCurr->next = NULL;
        pCurrLDD = pCurr->pldd;
    }
    else
    {
        pCurrLDD = pCurr->pldd;
	if (pCurrLDD->pszPath)		HeapFree(heap, 0, pCurrLDD->pszPath);
	if (pCurrLDD->pszVolLabel)	HeapFree(heap, 0, pCurrLDD->pszVolLabel);
	if (pCurrLDD->pszDiskName)	HeapFree(heap, 0, pCurrLDD->pszDiskName);
    }

    memcpy(pCurrLDD, pldd, sizeof(LOGDISKDESC_S));

    if (pldd->pszPath)
    {
        pCurrLDD->pszPath = HeapAlloc( heap, 0, strlen(pldd->pszPath)+1 );
        strcpy( pCurrLDD->pszPath, pldd->pszPath );
    }
    if (pldd->pszVolLabel)
    {
        pCurrLDD->pszVolLabel = HeapAlloc( heap, 0, strlen(pldd->pszVolLabel)+1 );
        strcpy( pCurrLDD->pszVolLabel, pldd->pszVolLabel );
    }
    if (pldd->pszDiskName)
    {
        pCurrLDD->pszDiskName = HeapAlloc( heap, 0, strlen(pldd->pszDiskName)+1 );
        strcpy( pCurrLDD->pszDiskName, pldd->pszDiskName );
    }

    if (is_new) /* link into list */
    {
        if (pPrev)
	{
	    pCurr->next = pPrev->next;
            pPrev->next = pCurr;
	}
	if (!pFirstLDD)
	    pFirstLDD = pCurr;
    }

    return OK;
}


/***********************************************************************
 * CtlAddLdd		(SETUPX.36)
 *
 * doesn't check pldd ptr validity: crash (W98SE)
 *
 */
static LOGDISKID16 ldid_to_add = LDID_ASSIGN_START;
RETERR16 WINAPI CtlAddLdd16(LPLOGDISKDESC pldd)
{
    pldd->ldid = ldid_to_add++;
    return CtlSetLdd16(pldd);
}

/***********************************************************************
 * CtlGetLdd		(SETUPX.34)
 *
 * doesn't check pldd ptr validity: crash (W98SE)
 * What the !@#$%&*( is the difference between CtlFindLdd() and CtlGetLdd() ??
 *
 * RETURN
 *   ERR_VCP_LDDINVALID if pldd->cbSize != structsize
 *
 */
static RETERR16 SETUPX_GetLdd(LPLOGDISKDESC pldd)
{
    LDD_LIST *pCurr, *pPrev = NULL;

    if (!std_LDDs_done)
	SETUPX_CreateStandardLDDs();

    if (pldd->cbSize != sizeof(LOGDISKDESC_S))
        return ERR_VCP_LDDINVALID;

    pCurr = pFirstLDD;
    /* search until we find the appropriate LDD or hit the end */
    while ((pCurr != NULL) && (pldd->ldid > pCurr->pldd->ldid))
    {
	 pPrev = pCurr;
	 pCurr = pCurr->next;
    }
    if (pCurr == NULL) /* hit end of list */
	return ERR_VCP_LDDFIND; /* correct ? */

    memcpy(pldd, pCurr->pldd, pldd->cbSize);
    /* hmm, we probably ought to strcpy() the string ptrs here */

    return OK;
}

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

RETERR16 WINAPI CtlGetLdd16(LPLOGDISKDESC pldd)
{
    FIXME("(%p); - please report to a.mohr@mailto.de !!!\n", pldd);
    return SETUPX_GetLdd(pldd);
}

/***********************************************************************
 *		CtlGetLddPath		(SETUPX.38)
 *
 * Gets the path of an LDD.
 * No crash if szPath == NULL.
 * szPath has to be at least MAX_PATH_LEN bytes long.
 * RETURN
 *   ERR_VCP_LDDUNINIT if LDD for LDID not found.
 */
RETERR16 WINAPI CtlGetLddPath16(LOGDISKID16 ldid, LPSTR szPath)
{
    TRACE("(%d, %p);\n", ldid, szPath);

    if (szPath)
    {
	LOGDISKDESC_S ldd;
	INIT_LDD(ldd, ldid);
	if (CtlFindLdd16(&ldd) == ERR_VCP_LDDFIND)
	    return ERR_VCP_LDDUNINIT;
	SETUPX_GetLdd(&ldd);
        strcpy(szPath, ldd.pszPath);
	TRACE("ret '%s' for LDID %d\n", szPath, ldid);
    }
    return OK;
}

/***********************************************************************
 *		CtlSetLddPath		(SETUPX.508)
 *
 * Sets the path of an LDD.
 * Creates LDD for LDID if not existing yet.
 */
RETERR16 WINAPI CtlSetLddPath16(LOGDISKID16 ldid, LPSTR szPath)
{
    LOGDISKDESC_S ldd;
    TRACE("(%d, '%s');\n", ldid, szPath);

    INIT_LDD(ldd, ldid);
    ldd.pszPath = szPath;
    return CtlSetLdd16(&ldd);
}

/*
 * Find the value of a custom LDID in a .inf file
 * e.g. for 49301:
 * 49300,49301=ProgramFilesDir,5
 * -- profile section lookup -->
 * [ProgramFilesDir]
 * HKLM,"Software\Microsoft\Windows\CurrentVersion","ProgramFilesDir",,"%24%"
 * -- GenFormStrWithoutPlaceHolders16 -->
 * HKLM,"Software\Microsoft\Windows\CurrentVersion","ProgramFilesDir",,"C:\"
 * -- registry lookup -->
 * C:\Program Files (or C:\ if not found in registry)
 *
 * FIXME:
 * - maybe we ought to add a caching array for speed ? - I don't care :)
 * - not sure whether the processing is correct - sometimes there are equal
 *   LDIDs for both install and removal sections.
 * - probably the whole function can be removed as installers add that on their
 *   own
 */
static BOOL SETUPX_AddCustomLDID(int ldid, INT16 hInf)
{
    char ldidstr[6];
    LPSTR sectionbuf = NULL, entrybuf = NULL, regsectionbuf = NULL;
    LPCSTR filename;
    LPSTR pSec, pEnt, pEqual, p, *pSub = NULL;
    BOOL ret = FALSE;
    char buffer[MAX_PATH];
    LOGDISKDESC_S ldd;

    sprintf(ldidstr, "%d", ldid);
    filename = IP_GetFileName(hInf);
    if (!(sectionbuf = SETUPX_GetSections(filename)))
    {
	ERR("couldn't get sections !\n");
	return FALSE;
    }
    for (pSec=sectionbuf; *pSec; pSec += strlen(pSec)+1)
    {
	if (!(entrybuf = SETUPX_GetSectionEntries(filename, pSec)))
	{
	    ERR("couldn't get section entries !\n");
	    goto end;
	}
	for (pEnt=entrybuf; *pEnt; pEnt += strlen(pEnt)+1)
	{
	    if (strstr(pEnt, ldidstr))
	    {
		pEqual = strchr(pEnt, '=');
		if (!pEqual) /* crippled entry ?? */
		    continue;

		/* make sure we found the LDID on left side of the equation */
		if (pEnt+strlen(ldidstr) <= pEqual)
		{ /* found */

		    /* but we don't want entries in the strings section */
		    if (!strcasecmp(pSec, "Strings")) continue;
		    p = pEqual+1;
		    goto found;
		}
	    }
	}
    }
    goto end;
found:
    TRACE("found entry '%s'\n", p);
    pSub = SETUPX_GetSubStrings(p, ',');
    if (*(DWORD *)pSub > 2)
    {
	ERR("malformed entry '%s' ?\n", p);
	goto end;
    }
    TRACE("found section '%s'\n", *(pSub+1));
    /* FIXME: what are the optional flags at the end of an entry used for ?? */

    /* get the location of the registry key from that section */
    if (!(regsectionbuf = SETUPX_GetSectionEntries(filename, *(pSub+1))))
    {
	ERR("couldn't get registry section entries !\n");
	goto end;
    }
    /* sectionbuf is > 1024 bytes anyway, so use it */
    GenFormStrWithoutPlaceHolders16(sectionbuf, regsectionbuf, hInf);
    ret = SETUPX_LookupRegistryString(sectionbuf, buffer, MAX_PATH);
    TRACE("return '%s'\n", buffer);
    INIT_LDD(ldd, ldid);
    ldd.pszPath = buffer;
    CtlSetLdd16(&ldd);
end:
    SETUPX_FreeSubStrings(pSub);
    if (sectionbuf)	HeapFree(GetProcessHeap(), 0, sectionbuf);
    if (entrybuf)	HeapFree(GetProcessHeap(), 0, entrybuf);
    if (regsectionbuf)	HeapFree(GetProcessHeap(), 0, regsectionbuf);
    return ret;
}

/*
 * Translate a logical disk identifier (LDID) into its string representation
 * I'm afraid this can be totally replaced by CtlGetLddPath().
 */
static BOOL SETUPX_IP_TranslateLDID(int ldid, LPSTR *p, HINF16 hInf)
{
    BOOL handled = FALSE;
    LOGDISKDESC_S ldd;

    ldd.cbSize = sizeof(LOGDISKDESC_S);
    ldd.ldid = ldid;
    if (CtlFindLdd16(&ldd) == ERR_VCP_LDDFIND)
    {
	/* hmm, it seems the installers already do the work for us
	 * (by calling CtlSetLddPath) that SETUPX_AddCustomLDID
	 * is supposed to do. Grmbl ;-)
	 * Well, I'll leave it here anyway, but print error... */
	ERR("hmm, LDID %d not registered yet !?\n", ldid);
	handled = SETUPX_AddCustomLDID(ldid, hInf);
    }
    else
	handled = TRUE;

    SETUPX_GetLdd(&ldd);

    if (!handled)
    {
        FIXME("What is LDID %d ??\n", ldid);
	*p = "LDID_FIXME";
    }
    else
	*p = ldd.pszPath;

    return handled;
}

/***********************************************************************
 *		GenFormStrWithoutPlaceHolders (SETUPX.103)
 *
 * ought to be pretty much implemented, I guess...
 */
void WINAPI GenFormStrWithoutPlaceHolders16( LPSTR szDst, LPCSTR szSrc, HINF16 hInf)
{
    LPCSTR pSrc = szSrc, pSrcEnd = szSrc + strlen(szSrc);
    LPSTR pDst = szDst, p, pPHBegin;
    int count;

    TRACE("(%p, '%s', %04x);\n", szDst, szSrc, hInf);
    while (pSrc < pSrcEnd)
    {
	p = strchr(pSrc, '%');
	if (p)
	{
	    count = (int)p - (int)pSrc;
	    strncpy(pDst, pSrc, count);
	    pSrc += count;
	    pDst += count;
	    pPHBegin = p+1;
	    p = strchr(pPHBegin, '%');
	    if (p)
	    {
		char placeholder[80]; /* that really ought to be enough ;) */
		int ldid;
		BOOL done = TRUE;
		count = (int)p - (int)pPHBegin;
		strncpy(placeholder, pPHBegin, count);
		placeholder[count] = '\0';
		ldid = atoi(placeholder);
		if (ldid)
		{
		    LPSTR p;
		    done = SETUPX_IP_TranslateLDID(ldid, &p, hInf);
		    strcpy(pDst, p);
		    if (done)
			pDst += strlen(pDst);
		}
		else
		{ /* hmm, string placeholder. Need to look up
		     in the [strings] section of the hInf */
		    DWORD ret;
		    char buf[256]; /* long enough ? */

		    ret = GetPrivateProfileStringA("strings", placeholder, "",
		    			buf, 256, IP_GetFileName(hInf));
		    if (ret)
		    {
			strcpy(pDst, buf);
			pDst += strlen(buf);
		    }
		    else
		    {
		        ERR("placeholder string '%s' not found !\n", placeholder);
			done = FALSE;
		    }
		}
		if (!done)
		{ /* copy raw placeholder string over */
		    count = (int)p - (int)pPHBegin + 2;
		    strncpy(pDst, pPHBegin-1, count);
		    pDst += count;

		}
		pSrc = p+1;
		continue;
	    }
	}

	/* copy the remaining source string over */
	strncpy(pDst, pSrc, (int)pSrcEnd - (int)pSrc + 1);
	break;
    }
    TRACE("ret '%s'\n", szDst);
}

/*
 * Copy all items in a CopyFiles entry over to the destination
 *
 * - VNLP_xxx is what is given as flags for a .INF CopyFiles section
 */
static BOOL SETUPX_CopyFiles(LPSTR *pSub, HINF16 hInf)
{
    BOOL bSingle = FALSE;
    unsigned int n;
    LPCSTR filename = IP_GetFileName(hInf);
    LPSTR pCopyEntry;
    char pDstStr[MAX_PATH];
    LPSTR pSrcDir, pDstDir;
    LPSTR pFileEntries, p;
    WORD ldid;
    LOGDISKDESC_S ldd;
    LPSTR *pSubFile;
    LPSTR pSrcFile, pDstFile;
    WORD flag;

    for (n=0; n < *(DWORD *)pSub; n++)
    {
	pCopyEntry = *(pSub+1+n);
	if (*pCopyEntry == '@')
	{
	    pCopyEntry++;
	    bSingle = TRUE;
	}
	else
	    bSingle = FALSE;

	/* get source directory for that entry */
	INIT_LDD(ldd, LDID_SRCPATH);
	SETUPX_GetLdd(&ldd);
	pSrcDir = ldd.pszPath;

        /* get destination directory for that entry */
	if (!(GetPrivateProfileStringA("DestinationDirs", pCopyEntry, "",
					pDstStr, sizeof(pDstStr), filename)))
	{
	    /* hmm, not found; try the default entry */
	    if (!(GetPrivateProfileStringA("DestinationDirs", "DefaultDestDir", "", pDstStr, sizeof(pDstStr), filename)))
	    {
		WARN("DefaultDestDir not found.\n");
	        continue;
	    }
	}

	/* translate destination dir if given as LDID */
	ldid = atoi(pDstStr);
	if (ldid)
	{
	    if (!(SETUPX_IP_TranslateLDID(ldid, &pDstDir, hInf)))
		continue;
	}
	else
	    pDstDir = pDstStr;

	/* now that we have the destination dir, register file copying */

	if (bSingle)
	{
	    VcpQueueCopy16(pCopyEntry, pCopyEntry, pSrcDir, pDstDir, LDID_SRCPATH, ldid ? ldid : 0xffff, 0, VFNL_COPY, 0);
	    return TRUE;
	}

	/* entry wasn't a single file, so let's iterate over section */
	pFileEntries = SETUPX_GetSectionEntries(filename, pCopyEntry);
        if (pFileEntries == NULL) continue;
        for (p=pFileEntries; *p; p +=strlen(p)+1)
	{
	    pSubFile = SETUPX_GetSubStrings(p, ',');
	    pSrcFile = *(pSubFile+1);
	    pDstFile = (*(DWORD *)pSubFile > 1) ? *(pSubFile+2) : pSrcFile;
	    TRACE("copying file '%s\\%s' to '%s\\%s'\n", pSrcDir, pSrcFile, pDstDir, pDstFile);
	    flag = 0;
	    if (*(DWORD *)pSubFile > 2)
	    {
		if ((flag = atoi(*(pSubFile+3)))) /* ah, flag */
		{
		    if (flag & 0x2c)
		    FIXME("VNLP_xxx flag %d not handled yet.\n", flag);
		}
		else
		{
		    FIXME("temp file name '%s' given. Need to register in wininit.ini !\n", *(pSubFile+3));
		    /* we probably need to set VIRTNODE.vhstrDstFinalName to
		     * the final destination name, and the temp name is merely
		     * the copy destination */
		}
	    }
	    VcpQueueCopy16(pSrcFile, pDstFile, pSrcDir, pDstDir, LDID_SRCPATH, ldid ? ldid : 0xffff, 0, VFNL_COPY|flag, 0);
	    SETUPX_FreeSubStrings(pSubFile);
	}
    }

    return TRUE;
}

/***********************************************************************
 *		GenInstall (SETUPX.101)
 *
 * generic installer function for .INF file sections
 *
 * This is not perfect - patch whenever you can !
 *
 * wFlags == GENINSTALL_DO_xxx
 * e.g. NetMeeting:
 * first call GENINSTALL_DO_REGSRCPATH | GENINSTALL_DO_FILES,
 * second call GENINSTALL_DO_LOGCONFIG | CFGAUTO | INI2REG | REG | INI
 */
RETERR16 WINAPI GenInstall16(HINF16 hInfFile, LPCSTR szInstallSection, WORD wFlags)
{
    LPCSTR filename = IP_GetFileName(hInfFile);
    LPSTR pEntries, p, pEnd;
    DWORD len;
    LPSTR *pSub;

    FIXME("(%04x, '%s', %04x), semi-stub. Please implement additional operations here !\n", hInfFile, szInstallSection, wFlags);
    pEntries = SETUPX_GetSectionEntries(filename, szInstallSection);
    if (!pEntries)
    {
	ERR("couldn't find entries for section '%s' !\n", szInstallSection);
	return ERR_IP_SECT_NOT_FOUND;
    }
    for (p=pEntries; *p; p +=strlen(p)+1)
    {
	pEnd = strchr(p, '=');
	if (!pEnd) continue;
	pSub = SETUPX_GetSubStrings(pEnd+1, ','); /* split entries after the '=' */
	SETUPX_IsolateSubString(&p, &pEnd);
	len = (int)pEnd - (int)p;

	if (wFlags & GENINSTALL_DO_FILES)
	{
	    if (!strncasecmp(p, "CopyFiles", len))
	    {
	        SETUPX_CopyFiles(pSub, hInfFile);
		continue;
	    }
#if IMPLEMENT_THAT
	    else
	    if (!strncasecmp(p, "DelFiles", len))
	    {
	        SETUPX_DelFiles(filename, szInstallSection, pSub);
		continue;
	    }
#endif
	}
	if (wFlags & GENINSTALL_DO_INI)
	{
#if IMPLEMENT_THAT
	    if (!strncasecmp(p, "UpdateInis", len))
	    {
	        SETUPX_UpdateInis(filename, szInstallSection, pSub);
		continue;
	    }
#endif
	}
	if (wFlags & GENINSTALL_DO_REG)
	{
#if IMPLEMENT_THAT
	    /* probably use SUReg*() functions here */
	    if (!strncasecmp(p, "AddReg", len))
	    {
	        SETUPX_AddReg(filename, szInstallSection, pSub);
		continue;
	    }
	    else
	    if (!strncasecmp(p, "DelReg", len))
	    {
	        SETUPX_DelReg(filename, szInstallSection, pSub);
		continue;
	    }
#endif
	}

	SETUPX_FreeSubStrings(pSub);
    }
    HeapFree(GetProcessHeap(), 0, pEntries);
    return OK;
}
