/*
 * Win32 builtin functions
 *
 * Copyright 1997 Alexandre Julliard
 */

#include "config.h"

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif

#include "windef.h"
#include "wine/winbase16.h"
#include "wine/library.h"
#include "module.h"
#include "file.h"
#include "heap.h"
#include "winerror.h"
#include "server.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(module);
DECLARE_DEBUG_CHANNEL(relay);

extern void RELAY_SetupDLL( const char *module );

static HMODULE main_module;

/***********************************************************************
 *           BUILTIN32_dlopen
 */
void *BUILTIN32_dlopen( const char *name )
{
    void *handle;
    char error[256];

    if (!(handle = wine_dll_load( name, error, sizeof(error) )))
    {
        if (strstr(error, "cannot open")) /* cannot open -> WARN() */
            WARN("cannot open .so lib for builtin %s: %s\n", name, error);
        else /* ERR() for all other errors (missing functions, ...) */
            ERR("failed to load .so lib for builtin %s: %s\n", name, error );
    }
    return handle;
}

/***********************************************************************
 *           BUILTIN32_dlclose
 */
int BUILTIN32_dlclose( void *handle )
{
    /* FIXME: should unregister descriptors first */
    /* wine_dll_unload( handle ); */
    return 0;
}


/***********************************************************************
 *           load_library
 *
 * Load a library in memory; callback function for wine_dll_register
 */
static void load_library( void *base, const char *filename )
{
    HMODULE module = (HMODULE)base;
    WINE_MODREF *wm;

    if (!base)
    {
        ERR("could not map image for %s\n", filename ? filename : "main exe" );
        return;
    }

    if (!(PE_HEADER(module)->FileHeader.Characteristics & IMAGE_FILE_DLL))
    {
        /* if we already have an executable, ignore this one */
        if (!main_module) main_module = module;
        return; /* don't create the modref here, will be done later on */
    }

    if (GetModuleHandleA( filename ))
        MESSAGE( "Warning: loading builtin %s, but native version already present. Expect trouble.\n", filename );

    /* Create 32-bit MODREF */
    if (!(wm = PE_CreateModule( module, filename, 0, 0, TRUE )))
    {
        ERR( "can't load %s\n", filename );
        SetLastError( ERROR_OUTOFMEMORY );
        return;
    }
    TRACE( "loaded %s %p %x\n", filename, wm, module );
    wm->refCount++;  /* we don't support freeing builtin dlls (FIXME)*/

    /* setup relay debugging entry points */
    if (TRACE_ON(relay)) RELAY_SetupDLL( (void *)module );
}


/***********************************************************************
 *           BUILTIN32_LoadLibraryExA
 *
 * Partly copied from the original PE_ version.
 *
 */
WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags)
{
    WINE_MODREF   *wm;
    char dllname[20], *p;
    LPCSTR name;
    void *handle;

    /* Fix the name in case we have a full path and extension */
    name = path;
    if ((p = strrchr( name, '\\' ))) name = p + 1;
    if ((p = strrchr( name, '/' ))) name = p + 1;

    if (strlen(name) >= sizeof(dllname)-4) goto error;

    strcpy( dllname, name );
    p = strrchr( dllname, '.' );
    if (!p) strcat( dllname, ".dll" );
    for (p = dllname; *p; p++) *p = FILE_tolower(*p);

    if (!(handle = BUILTIN32_dlopen( dllname ))) goto error;

    if (!(wm = MODULE_FindModule( path ))) wm = MODULE_FindModule( dllname );
    if (!wm)
    {
        ERR( "loaded .so but dll %s still not found\n", dllname );
        /* wine_dll_unload( handle );*/
        return NULL;
    }
    wm->dlhandle = handle;
    return wm;

 error:
    SetLastError( ERROR_FILE_NOT_FOUND );
    return NULL;
}

/***********************************************************************
 *           BUILTIN32_Init
 *
 * Initialize loading callbacks and return HMODULE of main exe.
 * 'main' is the main exe in case if was already loaded from a PE file.
 */
HMODULE BUILTIN32_LoadExeModule( HMODULE main )
{
    main_module = main;
    wine_dll_set_callback( load_library );
    if (!main_module)
        MESSAGE( "No built-in EXE module loaded!  Did you create a .spec file?\n" );
    return main_module;
}


/***********************************************************************
 *           BUILTIN32_RegisterDLL
 *
 * Register a built-in DLL descriptor.
 */
void BUILTIN32_RegisterDLL( const IMAGE_NT_HEADERS *header, const char *filename )
{
    extern void __wine_dll_register( const IMAGE_NT_HEADERS *header, const char *filename );
    __wine_dll_register( header, filename );
}
