/*
 * 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"


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;
    WCHAR* nameW;
    unsigned len;

    SymSetOptions((opts & ~(SYMOPT_UNDNAME|SYMOPT_DEFERRED_LOADS)) |
                  SYMOPT_LOAD_LINES | SYMOPT_AUTO_PUBLICS | 0x40000000);
    if (!dbg_init(hDummy, NULL, FALSE))
        return start_error_init;
    len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
    nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!nameW)
    {
        ret = start_error_init;
        keep = FALSE;
    }
    else
    {
        len = MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, len);
        if (!dbg_load_module(hDummy, NULL, nameW, 0, 0))
        {
            ret = start_error_init;
            keep = FALSE;
        }
        HeapFree(GetProcessHeap(), 0, nameW);
    }

    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,
};
