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

#include <assert.h>
#include <ctype.h>
#include <string.h>
#include "windows.h"
#include "gdi.h"
#include "global.h"
#include "module.h"
#include "miscemu.h"
#include "neexe.h"
#include "stackframe.h"
#include "user.h"
#include "stddebug.h"
#include "debug.h"

/* Built-in modules descriptors */
/* Don't change these structures! (see tools/build.c) */

typedef struct
{
    const BYTE *code_start;        /* 32-bit address of DLL code */
    const BYTE *data_start;        /* 32-bit address of DLL data */
} WIN16_DESCRIPTOR;

typedef struct
{
    int                 base;       /* Ordinal base */
    int                 size;       /* Number of functions */
    const void         *code_start; /* Start of DLL code */
    const void        **functions;  /* Pointer to functions table */
    const char * const *names;      /* Pointer to names table */
} WIN32_DESCRIPTOR;

typedef struct
{
    const char *name;              /* DLL name */
    void       *module_start;      /* 32-bit address of the module data */
    int         module_size;       /* Size of the module data */
    union
    {
        WIN16_DESCRIPTOR win16;    /* Descriptor for Win16 DLL */
        WIN32_DESCRIPTOR win32;    /* Descriptor for Win32 DLL */
    } u;
} DLL_DESCRIPTOR;

typedef struct
{
    const DLL_DESCRIPTOR *descr;   /* DLL descriptor */
    int                   flags;   /* flags (see below) */
} BUILTIN_DLL;


/* DLL flags */
#define DLL_FLAG_NOT_USED    0x01  /* Use original Windows DLL if possible */
#define DLL_FLAG_ALWAYS_USED 0x02  /* Always use built-in DLL */
#define DLL_FLAG_WIN32       0x04  /* DLL is a Win32 DLL */

/* 16-bit DLLs */

extern const DLL_DESCRIPTOR KERNEL_Descriptor;
extern const DLL_DESCRIPTOR USER_Descriptor;
extern const DLL_DESCRIPTOR GDI_Descriptor;
extern const DLL_DESCRIPTOR WIN87EM_Descriptor;
extern const DLL_DESCRIPTOR MMSYSTEM_Descriptor;
extern const DLL_DESCRIPTOR SHELL_Descriptor;
extern const DLL_DESCRIPTOR SOUND_Descriptor;
extern const DLL_DESCRIPTOR KEYBOARD_Descriptor;
extern const DLL_DESCRIPTOR WINSOCK_Descriptor;
extern const DLL_DESCRIPTOR STRESS_Descriptor;
extern const DLL_DESCRIPTOR SYSTEM_Descriptor;
extern const DLL_DESCRIPTOR TOOLHELP_Descriptor;
extern const DLL_DESCRIPTOR MOUSE_Descriptor;
extern const DLL_DESCRIPTOR COMMDLG_Descriptor;
extern const DLL_DESCRIPTOR OLE2_Descriptor;
extern const DLL_DESCRIPTOR OLE2CONV_Descriptor;
extern const DLL_DESCRIPTOR OLE2DISP_Descriptor;
extern const DLL_DESCRIPTOR OLE2NLS_Descriptor;
extern const DLL_DESCRIPTOR OLE2PROX_Descriptor;
extern const DLL_DESCRIPTOR OLECLI_Descriptor;
extern const DLL_DESCRIPTOR OLESVR_Descriptor;
extern const DLL_DESCRIPTOR COMPOBJ_Descriptor;
extern const DLL_DESCRIPTOR STORAGE_Descriptor;
extern const DLL_DESCRIPTOR WPROCS_Descriptor;
extern const DLL_DESCRIPTOR DDEML_Descriptor;
extern const DLL_DESCRIPTOR LZEXPAND_Descriptor;
extern const DLL_DESCRIPTOR VER_Descriptor;
extern const DLL_DESCRIPTOR W32SYS_Descriptor;
extern const DLL_DESCRIPTOR WING_Descriptor;

/* 32-bit DLLs */

extern const DLL_DESCRIPTOR ADVAPI32_Descriptor;
extern const DLL_DESCRIPTOR COMCTL32_Descriptor;
extern const DLL_DESCRIPTOR COMDLG32_Descriptor;
extern const DLL_DESCRIPTOR CRTDLL_Descriptor;
extern const DLL_DESCRIPTOR OLE32_Descriptor;
extern const DLL_DESCRIPTOR GDI32_Descriptor;
extern const DLL_DESCRIPTOR KERNEL32_Descriptor;
extern const DLL_DESCRIPTOR LZ32_Descriptor;
extern const DLL_DESCRIPTOR MPR_Descriptor;
extern const DLL_DESCRIPTOR NTDLL_Descriptor;
extern const DLL_DESCRIPTOR SHELL32_Descriptor;
extern const DLL_DESCRIPTOR USER32_Descriptor;
extern const DLL_DESCRIPTOR VERSION_Descriptor;
extern const DLL_DESCRIPTOR WINMM_Descriptor;
extern const DLL_DESCRIPTOR WINSPOOL_Descriptor;
extern const DLL_DESCRIPTOR WSOCK32_Descriptor;

/* Table of all built-in DLLs */

static BUILTIN_DLL BuiltinDLLs[] =
{
    /* Win16 DLLs */
    { &KERNEL_Descriptor,   DLL_FLAG_ALWAYS_USED },
    { &USER_Descriptor,     DLL_FLAG_ALWAYS_USED },
    { &GDI_Descriptor,      DLL_FLAG_ALWAYS_USED },
    { &WIN87EM_Descriptor,  DLL_FLAG_NOT_USED },
    { &SHELL_Descriptor,    0 },
    { &SOUND_Descriptor,    0 },
    { &KEYBOARD_Descriptor, 0 },
    { &WINSOCK_Descriptor,  0 },
    { &STRESS_Descriptor,   0 },
    { &MMSYSTEM_Descriptor, 0 },
    { &SYSTEM_Descriptor,   0 },
    { &TOOLHELP_Descriptor, 0 },
    { &MOUSE_Descriptor,    0 },
    { &COMMDLG_Descriptor,  DLL_FLAG_NOT_USED },
    { &OLE2_Descriptor,     DLL_FLAG_NOT_USED },
    { &OLE2CONV_Descriptor, DLL_FLAG_NOT_USED },
    { &OLE2DISP_Descriptor, DLL_FLAG_NOT_USED },
    { &OLE2NLS_Descriptor,  DLL_FLAG_NOT_USED },
    { &OLE2PROX_Descriptor, DLL_FLAG_NOT_USED },
    { &OLECLI_Descriptor,   DLL_FLAG_NOT_USED },
    { &OLESVR_Descriptor,   DLL_FLAG_NOT_USED },
    { &COMPOBJ_Descriptor,  DLL_FLAG_NOT_USED },
    { &STORAGE_Descriptor,  DLL_FLAG_NOT_USED },
    { &WPROCS_Descriptor,   DLL_FLAG_ALWAYS_USED },
    { &DDEML_Descriptor,    DLL_FLAG_NOT_USED },
    { &LZEXPAND_Descriptor, 0 },
    { &VER_Descriptor,      0 },
    { &W32SYS_Descriptor,   0 },
    { &WING_Descriptor,     0 },
    /* Win32 DLLs */
    { &ADVAPI32_Descriptor, 0 },
    { &COMCTL32_Descriptor, DLL_FLAG_NOT_USED },
    { &COMDLG32_Descriptor, DLL_FLAG_NOT_USED },
    { &CRTDLL_Descriptor,   0 },
    { &OLE32_Descriptor,    DLL_FLAG_NOT_USED },
    { &GDI32_Descriptor,    0 },
    { &KERNEL32_Descriptor, DLL_FLAG_ALWAYS_USED },
    { &LZ32_Descriptor,     0 },
    { &MPR_Descriptor,      0 },
    { &NTDLL_Descriptor,    0 },
    { &SHELL32_Descriptor,  0 },
    { &USER32_Descriptor,   0 },
    { &VERSION_Descriptor,  0 },
    { &WINMM_Descriptor,    0 },
    { &WINSPOOL_Descriptor, 0 },
    { &WSOCK32_Descriptor,  0 },
    /* Last entry */
    { NULL, 0 }
};

  /* Ordinal number for interrupt 0 handler in WPROCS.DLL */
#define FIRST_INTERRUPT_ORDINAL 100

/***********************************************************************
 *           BUILTIN_Init
 *
 * Load all built-in modules marked as 'always used'.
 */
BOOL16 BUILTIN_Init(void)
{
    BUILTIN_DLL *dll;
    NE_MODULE *pModule;
    WORD vector;
    HMODULE16 hModule;

    for (dll = BuiltinDLLs; dll->descr; dll++)
        if (dll->flags & DLL_FLAG_ALWAYS_USED)
            if (!BUILTIN_LoadModule(dll->descr->name, TRUE)) return FALSE;

    /* Set the USER and GDI heap selectors */

    pModule      = MODULE_GetPtr( GetModuleHandle16( "USER" ));
    USER_HeapSel = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;
    pModule      = MODULE_GetPtr( GetModuleHandle16( "GDI" ));
    GDI_HeapSel  = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;

    /* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */

    hModule = GetModuleHandle16( "KERNEL" );
    MODULE_SetEntryPoint( hModule, 178, GetWinFlags() );

    /* Initialize the real-mode selector entry points */

    DOSMEM_InitExports( hModule );

    /* Set interrupt vectors from entry points in WPROCS.DLL */

    hModule = GetModuleHandle16( "WPROCS" );
    for (vector = 0; vector < 256; vector++)
    {
        FARPROC16 proc = MODULE_GetEntryPoint( hModule,
                                               FIRST_INTERRUPT_ORDINAL+vector);
        assert(proc);
        INT_SetHandler( vector, proc );
    }

    return TRUE;
}


/***********************************************************************
 *           BUILTIN_LoadModule
 *
 * Load a built-in module. If the 'force' parameter is FALSE, we only
 * load the module if it has not been disabled via the -dll option.
 */
HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL16 force )
{
    HMODULE16 hModule;
    NE_MODULE *pModule;
    BUILTIN_DLL *table;
    char dllname[16], *p;

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

    if ((p = strrchr( name, '\\' ))) name = p + 1;
    lstrcpyn32A( dllname, name, sizeof(dllname) );
    if ((p = strrchr( dllname, '.' ))) *p = '\0';

    for (table = BuiltinDLLs; table->descr; table++)
        if (!lstrcmpi32A( table->descr->name, dllname )) break;
    if (!table->descr) return 0;
    if ((table->flags & DLL_FLAG_NOT_USED) && !force) return 0;

    hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, table->descr->module_start,
                                  table->descr->module_size, 0,
                                  FALSE, FALSE, FALSE, NULL );
    if (!hModule) return 0;
    FarSetOwner( hModule, hModule );

    dprintf_module( stddeb, "Built-in %s: hmodule=%04x\n",
                    table->descr->name, hModule );
    pModule = (NE_MODULE *)GlobalLock16( hModule );
    pModule->self = hModule;

    if (pModule->flags & NE_FFLAGS_WIN32)
    {
        pModule->pe_module = (PE_MODULE *)table;
        table->flags |= DLL_FLAG_WIN32;
    }
    else  /* Win16 module */
    {
        const WIN16_DESCRIPTOR *descr = &table->descr->u.win16;
        int minsize;

        /* Allocate the code segment */

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

        /* Allocate the data segment */

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

    MODULE_RegisterModule( pModule );
    return hModule;
}


/***********************************************************************
 *           BUILTIN_GetEntryPoint16
 *
 * Return the ordinal and name corresponding to a CS:IP address.
 * This is used only by relay debugging.
 */
LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd )
{
    static char buffer[80];
    WORD ordinal, i, max_offset;
    register BYTE *p;
    NE_MODULE *pModule;

    if (!(pModule = MODULE_GetPtr( FarGetOwner( GlobalHandle16(cs) ))))
        return NULL;

    /* Search for the ordinal */

    p = (BYTE *)pModule + pModule->entry_table;
    max_offset = 0;
    ordinal = 1;
    *pOrd = 0;
    while (*p)
    {
        switch(p[1])
        {
        case 0:    /* unused */
            ordinal += *p;
            p += 2;
            break;
        case 1:    /* code segment */
            i = *p;
            p += 2;
            while (i-- > 0)
            {
                p++;
                if ((*(WORD *)p <= ip) && (*(WORD *)p >= max_offset))
                {
                    max_offset = *(WORD *)p;
                    *pOrd = ordinal;
                }
                p += 2;
                ordinal++;
            }
            break;
        case 0xff: /* moveable (should not happen in built-in modules) */
            fprintf( stderr, "Built-in module has moveable entry\n" );
            ordinal += *p;
            p += 2 + *p * 6;
            break;
        default:   /* other segment */
            ordinal += *p;
            p += 2 + *p * 3;
            break;
        }
    }

    /* 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( buffer, "%.*s.%d: %.*s",
             *((BYTE *)pModule + pModule->name_table),
             (char *)pModule + pModule->name_table + 1,
             *pOrd, *p, (char *)(p + 1) );
    return buffer;
}


/***********************************************************************
 *           BUILTIN_GetEntryPoint32
 *
 * Return the name of the DLL entry point corresponding
 * to a relay entry point address. This is used only by relay debugging.
 */
LPCSTR BUILTIN_GetEntryPoint32( void *relay )
{
    static char buffer[80];
    BUILTIN_DLL *dll;
    const void **funcs;
    int i;

    /* First find the module */

    for (dll = BuiltinDLLs; dll->descr; dll++)
        if ((dll->flags & DLL_FLAG_WIN32) &&
            (dll->descr->u.win32.code_start <= relay) &&
            ((void *)dll->descr->u.win32.functions > relay))
            break;
    if (!dll->descr)
    {
        sprintf( buffer, "???.???: %08x", (UINT32)relay );
        return buffer;
    }

    /* Now find the function */

    relay = (BYTE *)relay - 11;  /* The relay entry point is 11 bytes long */
    funcs = dll->descr->u.win32.functions;
    for (i = 0; i < dll->descr->u.win32.size;i++) if (*funcs++ == relay) break;
    sprintf( buffer, "%s.%d: %s",
             dll->descr->name, i, dll->descr->u.win32.names[i] );
    return buffer;
}


/***********************************************************************
 *           BUILTIN_GetProcAddress32
 *
 * Implementation of GetProcAddress() for built-in Win32 modules.
 * FIXME: this should be unified with the real GetProcAddress32().
 */
FARPROC32 BUILTIN_GetProcAddress32( NE_MODULE *pModule, LPCSTR function )
{
    BUILTIN_DLL *dll = (BUILTIN_DLL *)pModule->pe_module;
    const WIN32_DESCRIPTOR *info = &dll->descr->u.win32;

    if (!dll) return NULL;

    if (HIWORD(function))  /* Find function by name */
    {
        int i;

        dprintf_module( stddeb, "Looking for function %s in %s\n",
                        function, dll->descr->name );
        for (i = 0; i < info->size; i++)
            if (info->names[i] && !strcmp( function, info->names[i] ))
                return (FARPROC32)info->functions[i];
    }
    else  /* Find function by ordinal */
    {
        WORD ordinal = LOWORD(function);
        dprintf_module( stddeb, "Looking for ordinal %d in %s\n",
                        ordinal, dll->descr->name );
        if (ordinal && ordinal < info->size)
            return (FARPROC32)info->functions[ordinal - info->base];
    }
    return NULL;
}


/**********************************************************************
 *	    BUILTIN_DefaultIntHandler
 *
 * Default interrupt handler.
 */
void BUILTIN_DefaultIntHandler( CONTEXT *context )
{
    WORD ordinal;
    STACK16FRAME *frame = CURRENT_STACK16;
    BUILTIN_GetEntryPoint16( frame->entry_cs, frame->entry_ip, &ordinal );
    INT_BARF( context, ordinal - FIRST_INTERRUPT_ORDINAL );
}


/***********************************************************************
 *           BUILTIN_ParseDLLOptions
 *
 * Set runtime DLL usage flags
 */
BOOL16 BUILTIN_ParseDLLOptions( const char *str )
{
    BUILTIN_DLL *dll;
    const char *p;

    while (*str)
    {
        while (*str && isspace(*str)) str++;
        if (!*str) return TRUE;
        if ((*str != '+') && (*str != '-')) return FALSE;
        str++;
        if (!(p = strchr( str, ',' ))) p = str + strlen(str);
        while ((p > str) && isspace(p[-1])) p--;
        if (p == str) return FALSE;
        for (dll = BuiltinDLLs; dll->descr; dll++)
        {
            if (!lstrncmpi32A( str, dll->descr->name, (int)(p - str) ))
            {
                if (str[-1] == '-')
                {
                    if (dll->flags & DLL_FLAG_ALWAYS_USED) return FALSE;
                    dll->flags |= DLL_FLAG_NOT_USED;
                }
                else dll->flags &= ~DLL_FLAG_NOT_USED;
                break;
            }
        }
        if (!dll->descr) return FALSE;
        str = p;
        while (*str && (isspace(*str) || (*str == ','))) str++;
    }
    return TRUE;
}


/***********************************************************************
 *           BUILTIN_PrintDLLs
 *
 * Print the list of built-in DLLs that can be disabled.
 */
void BUILTIN_PrintDLLs(void)
{
    int i;
    BUILTIN_DLL *dll;

    for (i = 0, dll = BuiltinDLLs; dll->descr; dll++)
    {
        if (!(dll->flags & DLL_FLAG_ALWAYS_USED))
            fprintf( stderr, "%-9s%c", dll->descr->name,
                     ((++i) % 8) ? ' ' : '\n' );
    }
    fprintf(stderr,"\n");
    exit(1);
}
