/*
 * Module/Library loadorder
 *
 * Copyright 1999 Bertho Stultiens
 */

#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "config.h"
#include "windef.h"
#include "winreg.h"
#include "winerror.h"
#include "options.h"
#include "file.h"
#include "module.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(module);

#define LOADORDER_ALLOC_CLUSTER	32	/* Allocate with 32 entries at a time */

typedef struct module_loadorder
{
    const char         *modulename;
    enum loadorder_type loadorder[LOADORDER_NTYPES];
} module_loadorder_t;

struct loadorder_list
{
    int                 count;
    int                 alloc;
    module_loadorder_t *order;
};

/* default load-order if nothing specified */
/* the list must remain sorted by dll name */
static module_loadorder_t default_order_list[] =
{
    { "display",      { LOADORDER_BI,  0,             0, 0 } },
    { "gdi",          { LOADORDER_BI,  0,             0, 0 } },
    { "gdi32",        { LOADORDER_BI,  0,             0, 0 } },
    { "glide2x",      { LOADORDER_SO,  LOADORDER_DLL, 0, 0 } },
    { "glide3x",      { LOADORDER_SO,  LOADORDER_DLL, 0, 0 } },
    { "icmp",         { LOADORDER_BI,  0,             0, 0 } },
    { "kernel",       { LOADORDER_BI,  0,             0, 0 } },
    { "kernel32",     { LOADORDER_BI,  0,             0, 0 } },
    { "keyboard",     { LOADORDER_BI,  0,             0, 0 } },
    { "krnl386",      { LOADORDER_BI,  0,             0, 0 } },
    { "mmsystem",     { LOADORDER_BI,  0,             0, 0 } },
    { "mouse",        { LOADORDER_BI,  0,             0, 0 } },
    { "ntdll",        { LOADORDER_BI,  0,             0, 0 } },
    { "odbc32",       { LOADORDER_BI,  0,             0, 0 } },
    { "system",       { LOADORDER_BI,  0,             0, 0 } },
    { "toolhelp",     { LOADORDER_BI,  0,             0, 0 } },
    { "ttydrv",       { LOADORDER_BI,  0,             0, 0 } },
    { "user",         { LOADORDER_BI,  0,             0, 0 } },
    { "user32",       { LOADORDER_BI,  0,             0, 0 } },
    { "w32skrnl",     { LOADORDER_BI,  0,             0, 0 } },
    { "winaspi",      { LOADORDER_BI,  0,             0, 0 } },
    { "windebug",     { LOADORDER_DLL, LOADORDER_BI,  0, 0 } },
    { "winedos",      { LOADORDER_BI,  0,             0, 0 } },
    { "wineps",       { LOADORDER_BI,  0,             0, 0 } },
    { "wing",         { LOADORDER_BI,  0,             0, 0 } },
    { "winmm",        { LOADORDER_BI,  0,             0, 0 } },
    { "winsock",      { LOADORDER_BI,  0,             0, 0 } },
    { "wnaspi32",     { LOADORDER_BI,  0,             0, 0 } },
    { "wow32",        { LOADORDER_BI,  0,             0, 0 } },
    { "wprocs",       { LOADORDER_BI,  0,             0, 0 } },
    { "ws2_32",       { LOADORDER_BI,  0,             0, 0 } },
    { "wsock32",      { LOADORDER_BI,  0,             0, 0 } },
    { "x11drv",       { LOADORDER_BI,  0,             0, 0 } }
};

static const struct loadorder_list default_list =
{
    sizeof(default_order_list)/sizeof(default_order_list[0]),
    sizeof(default_order_list)/sizeof(default_order_list[0]),
    default_order_list
};

static struct loadorder_list cmdline_list;


/***************************************************************************
 *	cmp_sort_func	(internal, static)
 *
 * Sorting and comparing function used in sort and search of loadorder
 * entries.
 */
static int cmp_sort_func(const void *s1, const void *s2)
{
    return FILE_strcasecmp(((module_loadorder_t *)s1)->modulename,
                           ((module_loadorder_t *)s2)->modulename);
}


/***************************************************************************
 *	get_tok	(internal, static)
 *
 * strtok wrapper for non-destructive buffer writing.
 * NOTE: strtok is not reentrant and therefore this code is neither.
 */
static char *get_tok(const char *str, const char *delim)
{
	static char *buf = NULL;
	char *cptr;

	if(!str && !buf)
		return NULL;

	if(str && buf)
	{
		HeapFree(GetProcessHeap(), 0, buf);
		buf = NULL;
	}

	if(str && !buf)
	{
		buf = HeapAlloc(GetProcessHeap(), 0, strlen(str)+1);
		strcpy( buf, str );
		cptr = strtok(buf, delim);
	}
	else
	{
		cptr = strtok(NULL, delim);
	}

	if(!cptr)
	{
		HeapFree(GetProcessHeap(), 0, buf);
		buf = NULL;
	}
	return cptr;
}


/***************************************************************************
 *	ParseLoadOrder	(internal, static)
 *
 * Parses the loadorder options from the configuration and puts it into
 * a structure.
 */
static BOOL ParseLoadOrder(char *order, enum loadorder_type lo[])
{
    static int warn;
	char *cptr;
	int n = 0;

	cptr = get_tok(order, ", \t");
	while(cptr)
	{
            enum loadorder_type type = LOADORDER_INVALID;

		if(n >= LOADORDER_NTYPES-1)
		{
			ERR("More than existing %d module-types specified, rest ignored\n", LOADORDER_NTYPES-1);
			break;
		}

		switch(*cptr)
		{
		case 'N':	/* Native */
		case 'n': type = LOADORDER_DLL; break;

		case 'E':	/* Elfdll */
		case 'e':
                    if (!warn++) MESSAGE("Load order 'elfdll' no longer supported, ignored\n");
                    break;
		case 'S':	/* So */
		case 's': type = LOADORDER_SO; break;

		case 'B':	/* Builtin */
		case 'b': type = LOADORDER_BI; break;

		default:
			ERR("Invalid load order module-type '%s', ignored\n", cptr);
		}

                if(type != LOADORDER_INVALID) lo[n++] = type;
		cptr = get_tok(NULL, ", \t");
	}
        lo[n] = LOADORDER_INVALID;
	return TRUE;
}


/***************************************************************************
 *	AddLoadOrder	(internal, static)
 *
 * Adds an entry in the list of command-line overrides.
 */
static BOOL AddLoadOrder(module_loadorder_t *plo)
{
	int i;

	/* TRACE(module, "'%s' -> %08lx\n", plo->modulename, *(DWORD *)(plo->loadorder)); */

	for(i = 0; i < cmdline_list.count; i++)
	{
            if(!cmp_sort_func(plo, &cmdline_list.order[i] ))
            {
                /* replace existing option */
                memcpy( cmdline_list.order[i].loadorder, plo->loadorder, sizeof(plo->loadorder));
                return TRUE;
            }
	}

	if (i >= cmdline_list.alloc)
	{
		/* No space in current array, make it larger */
		cmdline_list.alloc += LOADORDER_ALLOC_CLUSTER;
		cmdline_list.order = HeapReAlloc(GetProcessHeap(), 0, cmdline_list.order,
                                          cmdline_list.alloc * sizeof(module_loadorder_t));
		if(!cmdline_list.order)
		{
			MESSAGE("Virtual memory exhausted\n");
			exit(1);
		}
	}
	memcpy(cmdline_list.order[i].loadorder, plo->loadorder, sizeof(plo->loadorder));
	cmdline_list.order[i].modulename = HeapAlloc(GetProcessHeap(), 0, strlen(plo->modulename)+1);
	strcpy( (char *)cmdline_list.order[i].modulename, plo->modulename );
	cmdline_list.count++;
	return TRUE;
}


/***************************************************************************
 *	AddLoadOrderSet	(internal, static)
 *
 * Adds a set of entries in the list of command-line overrides from the key parameter.
 */
static BOOL AddLoadOrderSet(char *key, char *order)
{
	module_loadorder_t ldo;
	char *cptr;

	/* Parse the loadorder before the rest because strtok is not reentrant */
	if(!ParseLoadOrder(order, ldo.loadorder))
		return FALSE;

	cptr = get_tok(key, ", \t");
	while(cptr)
	{
		char *ext = strrchr(cptr, '.');
		if(ext)
		{
			if(strlen(ext) == 4 &&
                           (!FILE_strcasecmp(ext, ".dll") || !FILE_strcasecmp(ext, ".exe")))
				MESSAGE("Warning: Loadorder override '%s' contains an extension and might not be found during lookup\n", cptr);
		}

		ldo.modulename = cptr;
		if(!AddLoadOrder(&ldo)) return FALSE;
		cptr = get_tok(NULL, ", \t");
	}
	return TRUE;
}


/***************************************************************************
 *	MODULE_AddLoadOrderOption
 *
 * The commandline option is in the form:
 * name[,name,...]=native[,b,...]
 */
void MODULE_AddLoadOrderOption( const char *option )
{
    char *value, *key = HeapAlloc(GetProcessHeap(), 0, strlen(option)+1);

    strcpy( key, option );
    if (!(value = strchr(key, '='))) goto error;
    *value++ = '\0';

    TRACE("Commandline override '%s' = '%s'\n", key, value);

    if (!AddLoadOrderSet(key, value)) goto error;
    HeapFree(GetProcessHeap(), 0, key);

    /* sort the array for quick lookup */
    qsort(cmdline_list.order, cmdline_list.count, sizeof(cmdline_list.order[0]), cmp_sort_func);
    return;

 error:
    MESSAGE( "Syntax: -dll name[,name[,...]]={native|so|builtin}[,{n|s|b}[,...]]\n"
             "    - 'name' is the name of any dll without extension\n"
             "    - the order of loading (native, so and builtin) can be abbreviated\n"
             "      with the first letter\n"
             "    - the option can be specified multiple times\n"
             "    Example:\n"
             "    -dll comdlg32,commdlg=n -dll shell,shell32=b\n" );
    ExitProcess(1);
}


/***************************************************************************
 *	set_registry_keys
 *
 * Set individual registry keys for a multiple dll specification
 * Helper for MODULE_InitLoadOrder().
 */
inline static void set_registry_keys( HKEY hkey, char *module, const char *buffer )
{
    static int warn;
    char *p = get_tok( module, ", \t" );

    TRACE( "converting \"%s\" = \"%s\"\n", module, buffer );

    if (!warn)
        MESSAGE( "Warning: setting multiple modules in a single DllOverrides entry is no longer\n"
                 "recommended. It is suggested that you rewrite the configuration file entry:\n\n"
                 "\"%s\" = \"%s\"\n\n"
                 "into something like:\n\n", module, buffer );
    while (p)
    {
        if (!warn) MESSAGE( "\"%s\" = \"%s\"\n", p, buffer );
        /* only set it if not existing already */
        if (RegQueryValueExA( hkey, p, 0, NULL, NULL, NULL ) == ERROR_FILE_NOT_FOUND)
            RegSetValueExA( hkey, p, 0, REG_SZ, buffer, strlen(buffer)+1 );
        p = get_tok( NULL, ", \t" );
    }
    if (!warn) MESSAGE( "\n" );
    warn = 1;
}


/***************************************************************************
 *	MODULE_InitLoadOrder
 *
 * Convert entries containing multiple dll names (old syntax) to the
 * new one dll module per entry syntax
 */
void MODULE_InitLoadOrder(void)
{
    char module[80];
    char buffer[1024];
    char *p;
    HKEY hkey;
    DWORD index = 0;

    if (RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\DllOverrides", &hkey ))
        return;

    for (;;)
    {
        DWORD type, count = sizeof(buffer), name_len = sizeof(module);

        if (RegEnumValueA( hkey, index, module, &name_len, NULL, &type, buffer, &count )) break;
        p = module;
        while (isspace(*p)) p++;
        p += strcspn( p, ", \t" );
        while (isspace(*p)) p++;
        if (*p)
        {
            RegDeleteValueA( hkey, module );
            set_registry_keys( hkey, module, buffer );
        }
        else index++;
    }
    RegCloseKey( hkey );
}


/***************************************************************************
 *	get_list_load_order
 *
 * Get the load order for a given module from the command-line or
 * default lists.
 */
static BOOL get_list_load_order( const char *module, const struct loadorder_list *list,
                                 enum loadorder_type lo[] )
{
    module_loadorder_t tmp, *res = NULL;

    tmp.modulename = module;
    /* some bsearch implementations (Solaris) are buggy when the number of items is 0 */
    if (list->count && (res = bsearch(&tmp, list->order, list->count, sizeof(list->order[0]), cmp_sort_func)))
        memcpy( lo, res->loadorder, sizeof(res->loadorder) );
    return (res != NULL);
}


/***************************************************************************
 *	get_app_load_order
 *
 * Get the load order for a given module from the app-specific DllOverrides list.
 * Also look for default '*' key if no module key found.
 */
static BOOL get_app_load_order( const char *module, enum loadorder_type lo[], BOOL *got_default )
{
    HKEY hkey, appkey;
    DWORD count, type, res;
    char buffer[MAX_PATH+16], *appname, *p;

    if (!GetModuleFileName16( GetCurrentTask(), buffer, MAX_PATH ) &&
        !GetModuleFileNameA( 0, buffer, MAX_PATH ))
    {
        WARN( "could not get module file name loading %s\n", module );
        return FALSE;
    }
    appname = buffer;
    if ((p = strrchr( appname, '/' ))) appname = p + 1;
    if ((p = strrchr( appname, '\\' ))) appname = p + 1;

    TRACE( "searching '%s' in AppDefaults\\%s\\DllOverrides\n", module, appname );

    if (RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\AppDefaults", &hkey ))
        return FALSE;

    /* open AppDefaults\\appname\\DllOverrides key */
    strcat( appname, "\\DllOverrides" );
    res = RegOpenKeyA( hkey, appname, &appkey );
    RegCloseKey( hkey );
    if (res) return FALSE;

    count = sizeof(buffer);
    if ((res = RegQueryValueExA( appkey, module, NULL, &type, buffer, &count )))
    {
        if (!(res = RegQueryValueExA( appkey, "*", NULL, &type, buffer, &count )))
            *got_default = TRUE;
    }
    else TRACE( "got app loadorder '%s' for '%s'\n", buffer, module );
    RegCloseKey( appkey );
    if (res) return FALSE;
    return ParseLoadOrder( buffer, lo );
}


/***************************************************************************
 *	get_standard_load_order
 *
 * Get the load order for a given module from the main DllOverrides list
 * Also look for default '*' key if no module key found.
 */
static BOOL get_standard_load_order( const char *module, enum loadorder_type lo[],
                                     BOOL *got_default )
{
    HKEY hkey;
    DWORD count, type, res;
    char buffer[80];

    if (RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\DllOverrides", &hkey ))
        return FALSE;

    count = sizeof(buffer);
    if ((res = RegQueryValueExA( hkey, module, NULL, &type, buffer, &count )))
    {
        if (!(res = RegQueryValueExA( hkey, "*", NULL, &type, buffer, &count )))
            *got_default = TRUE;
    }
    else TRACE( "got standard loadorder '%s' for '%s'\n", buffer, module );
    RegCloseKey( hkey );
    if (res) return FALSE;
    return ParseLoadOrder( buffer, lo );
}


/***************************************************************************
 *	get_default_load_order
 *
 * Get the default load order if nothing specified for a given dll.
 */
static void get_default_load_order( enum loadorder_type lo[] )
{
    DWORD res;
    static enum loadorder_type default_loadorder[LOADORDER_NTYPES];
    static int loaded;

    if (!loaded)
    {
        char buffer[80];
        HKEY hkey;

        if (!(res = RegOpenKeyA( HKEY_LOCAL_MACHINE,
                                 "Software\\Wine\\Wine\\Config\\DllDefaults", &hkey )))
        {
            DWORD type, count = sizeof(buffer);

            res = RegQueryValueExA( hkey, "DefaultLoadOrder", NULL, &type, buffer, &count );
            RegCloseKey( hkey );
        }
        if (res) strcpy( buffer, "n,b,s" );
        ParseLoadOrder( buffer, default_loadorder );
        loaded = 1;
        TRACE( "got default loadorder '%s'\n", buffer );
    }
    memcpy( lo, default_loadorder, sizeof(default_loadorder) );
}


/***************************************************************************
 *	MODULE_GetLoadOrder	(internal)
 *
 * Locate the loadorder of a module.
 * Any path is stripped from the path-argument and so are the extension
 * '.dll' and '.exe'. A lookup in the table can yield an override for
 * the specific dll. Otherwise the default load order is returned.
 */
void MODULE_GetLoadOrder( enum loadorder_type loadorder[], const char *path, BOOL win32 )
{
	char fname[256];
	char sysdir[MAX_PATH+1];
	char *cptr;
	char *name;
	int len;
        BOOL got_app_default = FALSE, got_std_default = FALSE;
        enum loadorder_type lo_default[LOADORDER_NTYPES];

	TRACE("looking for %s\n", path);

        if ( ! GetSystemDirectoryA ( sysdir, MAX_PATH ) ) goto done;

	/* Strip path information for 16 bit modules or if the module 
	   resides in the system directory */
	if ( !win32 || !FILE_strncasecmp ( sysdir, path, strlen (sysdir) ) )
	{
	
	    cptr = strrchr(path, '\\');
	    if(!cptr)
	        name = strrchr(path, '/');
	    else
	        name = strrchr(cptr, '/');
	    
	    if(!name)
	        name = cptr ? cptr+1 : (char *)path;
	    else
	        name++;
	    
	    if((cptr = strchr(name, ':')) != NULL)	/* Also strip drive if in format 'C:MODULE.DLL' */
	        name = cptr+1;
	}
	else 
	  name = (char *)path;
    
	len = strlen(name);
	if(len >= sizeof(fname) || len <= 0)
	{
            WARN("Path '%s' -> '%s' reduces to zilch or just too large...\n", path, name);
            goto done;
	}

	strcpy(fname, name);
	if(len >= 4 && (!FILE_strcasecmp(fname+len-4, ".dll") || !FILE_strcasecmp(fname+len-4, ".exe")))
		fname[len-4] = '\0';

        /* check command-line first */
        if (get_list_load_order( fname, &cmdline_list, loadorder )) return;

        /* then app-specific config */
        if (get_app_load_order( fname, loadorder, &got_app_default ))
        {
            if (!got_app_default) return;
            /* save the default value for later on */
            memcpy( lo_default, loadorder, sizeof(lo_default) );
        }

        /* then standard config */
        if (get_standard_load_order( fname, loadorder, &got_std_default ))
        {
            if (!got_std_default) return;
            /* save the default value for later on */
            if (!got_app_default) memcpy( lo_default, loadorder, sizeof(lo_default) );
        }

        /* then compiled-in defaults */
        if (get_list_load_order( fname, &default_list, loadorder )) return;

 done:
        /* last, return the default */
        if (got_app_default || got_std_default)
            memcpy( loadorder, lo_default, sizeof(lo_default) );
        else
            get_default_load_order( loadorder );
}
