/*
 *      SETUPX library
 *
 *      Copyright 1998,2000  Andreas Mohr
 *
 * 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 "debugtools.h"

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);
        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;
}
