/*
 * Wine debugger - loading a module for debug purposes
 *
 * Copyright 2006 Eric Pouech
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "config.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#include "debugger.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winedbg);

static struct be_process_io be_process_module_io;

static BOOL WINAPI tgt_process_module_read(HANDLE hProcess, const void* addr,
                                             void* buffer, SIZE_T len, SIZE_T* rlen)
{
    return FALSE;
}

static BOOL WINAPI tgt_process_module_write(HANDLE hProcess, void* addr,
                                             const void* buffer, SIZE_T len, SIZE_T* wlen)
{
    return FALSE;
}

enum dbg_start tgt_module_load(const char* name, BOOL keep)
{
    DWORD opts = SymGetOptions();
    HANDLE hDummy = (HANDLE)0x87654321;
    enum dbg_start ret = start_ok;

    SymSetOptions((opts & ~(SYMOPT_UNDNAME|SYMOPT_DEFERRED_LOADS)) |
                  SYMOPT_LOAD_LINES | SYMOPT_AUTO_PUBLICS | 0x40000000);
    if (!dbg_init(hDummy, NULL, FALSE))
        return start_error_init;
    if (!SymLoadModule(hDummy, NULL, name, NULL, 0, 0))
    {
        ret = start_error_init;
        keep = FALSE;
    }

    if (keep)
    {
        dbg_printf("Non supported mode... errors may occur\n"
                   "Use at your own risks\n");
        SymSetOptions(SymGetOptions() | 0x40000000);
        dbg_curr_process = dbg_add_process(&be_process_module_io, 1, hDummy);
        dbg_curr_pid = 1;
        dbg_curr_thread = dbg_add_thread(dbg_curr_process, 2, NULL, NULL);

        /* FIXME: missing thread creation, fetching frames, restoring dbghelp's options... */
    }
    else
    {
        SymCleanup(hDummy);
        SymSetOptions(opts);
    }

    return ret;
}

static BOOL tgt_process_module_close_process(struct dbg_process* pcs, BOOL kill)
{
    SymCleanup(pcs->handle);
    dbg_del_process(pcs);
    return TRUE;
}

static BOOL WINAPI tgt_process_module_get_selector(HANDLE hThread, DWORD sel, LDT_ENTRY* le)
{
    return FALSE;
}

static struct be_process_io be_process_module_io =
{
    tgt_process_module_close_process,
    tgt_process_module_read,
    tgt_process_module_write,
    tgt_process_module_get_selector,
};
