/*
 * Built-in modules
 *
 * Copyright 1996 Alexandre Julliard
 */

#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "winbase.h"
#include "wine/winbase16.h"
#include "wine/winestring.h"
#include "builtin16.h"
#include "builtin32.h"
#include "global.h"
#include "heap.h"
#include "module.h"
#include "miscemu.h"
#include "stackframe.h"
#include "process.h"
#include "task.h"
#include "debugtools.h"
#include "toolhelp.h"

DEFAULT_DEBUG_CHANNEL(module);

typedef struct
{
    LPVOID  res_start;          /* address of resource data */
    DWORD   nr_res;
    DWORD   res_size;           /* size of resource data */
} BUILTIN16_RESOURCE;


/* Table of all built-in DLLs */

#define MAX_DLLS 50

static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS];
static int nb_dlls;


/***********************************************************************
 *           BUILTIN_DoLoadModule16
 *
 * Load a built-in Win16 module. Helper function for BUILTIN_LoadModule.
 */
static HMODULE16 BUILTIN_DoLoadModule16( const BUILTIN16_DESCRIPTOR *descr )
{
    NE_MODULE *pModule;
    int minsize, res_off;
    SEGTABLEENTRY *pSegTable;
    HMODULE16 hModule;
    const BUILTIN16_RESOURCE *rsrc = descr->rsrc;

    if (!rsrc)
    {
        hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, descr->module_start,
                                      descr->module_size, 0,
                                            FALSE, FALSE, FALSE, NULL );
        if (!hModule) return 0;
        FarSetOwner16( hModule, hModule );

        pModule = (NE_MODULE *)GlobalLock16( hModule );
    }
    else
    {
        ET_BUNDLE *bundle;

        hModule = GLOBAL_Alloc( GMEM_MOVEABLE, 
                                descr->module_size + rsrc->res_size, 
                                0, FALSE, FALSE, FALSE );
        if (!hModule) return 0;
        FarSetOwner16( hModule, hModule );

        pModule = (NE_MODULE *)GlobalLock16( hModule );
        res_off = ((NE_MODULE *)descr->module_start)->res_table;

        memcpy( (LPBYTE)pModule, descr->module_start, res_off );
        memcpy( (LPBYTE)pModule + res_off, rsrc->res_start, rsrc->res_size );
        memcpy( (LPBYTE)pModule + res_off + rsrc->res_size, 
                (LPBYTE)descr->module_start + res_off, descr->module_size - res_off );

        /* Have to fix up various pModule-based near pointers.  Ugh! */
        pModule->name_table   += rsrc->res_size;
        pModule->modref_table += rsrc->res_size;
        pModule->import_table += rsrc->res_size;
        pModule->entry_table  += rsrc->res_size;

        for ( bundle = (ET_BUNDLE *)((LPBYTE)pModule + pModule->entry_table);
              bundle->next;
              bundle = (ET_BUNDLE *)((LPBYTE)pModule + bundle->next) )
            bundle->next += rsrc->res_size;

        /* NOTE: (Ab)use the hRsrcMap parameter for resource data pointer */
        pModule->hRsrcMap = rsrc->res_start;
    }
    pModule->self = hModule;

    TRACE( "Built-in %s: hmodule=%04x\n", descr->name, hModule );

    /* Allocate the code segment */

    pSegTable = NE_SEG_TABLE( pModule );
    pSegTable->hSeg = GLOBAL_CreateBlock( GMEM_FIXED, descr->code_start,
                                              pSegTable->minsize, hModule,
                                              TRUE, TRUE, FALSE, NULL );
    if (!pSegTable->hSeg) return 0;
    pSegTable++;

    /* Allocate the data segment */

    minsize = pSegTable->minsize ? pSegTable->minsize : 0x10000;
    minsize += pModule->heap_size;
    if (minsize > 0x10000) minsize = 0x10000;
    pSegTable->hSeg = GLOBAL_Alloc( GMEM_FIXED, minsize,
                                        hModule, FALSE, FALSE, FALSE );
    if (!pSegTable->hSeg) return 0;
    if (pSegTable->minsize) memcpy( GlobalLock16( pSegTable->hSeg ),
                                    descr->data_start, pSegTable->minsize);
    if (pModule->heap_size)
        LocalInit16( GlobalHandleToSel16(pSegTable->hSeg),
		pSegTable->minsize, minsize );

	if (rsrc)
		NE_InitResourceHandler(hModule);

    NE_RegisterModule( pModule );
    return hModule;
}


/***********************************************************************
 *           BUILTIN_LoadModule
 *
 * Load a built-in module.
 */
HMODULE16 BUILTIN_LoadModule( LPCSTR name )
{
    char dllname[16], *p;
    void *handle;
    int i;

    /* Fix the name in case we have a full path and extension */

    if ((p = strrchr( name, '\\' ))) name = p + 1;
    lstrcpynA( dllname, name, sizeof(dllname) );
    p = strrchr( dllname, '.' );
	 
    if (!p) strcat( dllname, ".dll" );

    for (i = 0; i < nb_dlls; i++)
    {
        const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i];
        NE_MODULE *pModule = (NE_MODULE *)descr->module_start;
        OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo);
        if (!strcasecmp( pOfs->szPathName, dllname ))
            return BUILTIN_DoLoadModule16( descr );
    }

    if ((handle = BUILTIN32_dlopen( dllname )))
    {
        for (i = 0; i < nb_dlls; i++)
        {
            const BUILTIN16_DESCRIPTOR *descr = builtin_dlls[i];
            NE_MODULE *pModule = (NE_MODULE *)descr->module_start;
            OFSTRUCT *pOfs = (OFSTRUCT *)((LPBYTE)pModule + pModule->fileinfo);
            if (!strcasecmp( pOfs->szPathName, dllname ))
                return BUILTIN_DoLoadModule16( descr );
        }
        ERR( "loaded .so but dll %s still not found\n", dllname );
        BUILTIN32_dlclose( handle );
    }

    return (HMODULE16)2;
}


/***********************************************************************
 *           BUILTIN_GetEntryPoint16
 *
 * Return the ordinal, name, and type info corresponding to a CS:IP address.
 * This is used only by relay debugging.
 */
LPCSTR BUILTIN_GetEntryPoint16( STACK16FRAME *frame, LPSTR name, WORD *pOrd )
{
    WORD i, max_offset;
    register BYTE *p;
    NE_MODULE *pModule;
    ET_BUNDLE *bundle;
    ET_ENTRY *entry;

    if (!(pModule = NE_GetPtr( FarGetOwner16( GlobalHandle16( frame->module_cs ) ))))
        return NULL;

    max_offset = 0;
    *pOrd = 0;
    bundle = (ET_BUNDLE *)((BYTE *)pModule + pModule->entry_table);
    do 
    {
        entry = (ET_ENTRY *)((BYTE *)bundle+6);
	for (i = bundle->first + 1; i <= bundle->last; i++)
        {
	    if ((entry->offs < frame->entry_ip)
	    && (entry->segnum == 1) /* code segment ? */
	    && (entry->offs >= max_offset))
            {
		max_offset = entry->offs;
		*pOrd = i;
            }
	    entry++;
        }
    } while ( (bundle->next)
	   && (bundle = (ET_BUNDLE *)((BYTE *)pModule+bundle->next)));

    /* Search for the name in the resident names table */
    /* (built-in modules have no non-resident table)   */
    
    p = (BYTE *)pModule + pModule->name_table;
    while (*p)
    {
        p += *p + 1 + sizeof(WORD);
        if (*(WORD *)(p + *p + 1) == *pOrd) break;
    }

    sprintf( name, "%.*s.%d: %.*s",
             *((BYTE *)pModule + pModule->name_table),
             (char *)pModule + pModule->name_table + 1,
             *pOrd, *p, (char *)(p + 1) );

    /* Retrieve type info string */
    return *(LPCSTR *)((LPBYTE)PTR_SEG_OFF_TO_LIN( frame->module_cs, frame->callfrom_ip ) + 4);
}


/***********************************************************************
 *           BUILTIN_RegisterDLL
 *
 * Register a built-in DLL descriptor.
 */
void BUILTIN_RegisterDLL( const BUILTIN16_DESCRIPTOR *descr )
{
    assert( nb_dlls < MAX_DLLS );
    builtin_dlls[nb_dlls++] = descr;
}
