/* Wine internal debugger
 * Interface to Windows debugger API
 * Copyright 2000-2004 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
 */

#include "config.h"
#include "wine/port.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "debugger.h"

#include "winternl.h"
#include "wine/exception.h"
#include "wine/library.h"

#include "wine/debug.h"

/* TODO list:
 *
 * - minidump
 *      + ensure that all commands work as expected in minidump reload function
 *        (and reenable parser usager)
 * - CPU adherence
 *      + we always assume the stack grows as on i386 (ie downwards)
 * - UI
 *      + enable back the limited output (depth of structure printing and number of 
 *        lines)
 *      + make the output as close as possible to what gdb does
 * - symbol management:
 *      + symbol table loading is broken
 *      + in symbol_get_lvalue, we don't do any scoping (as C does) between local and
 *        global vars (we may need this to force some display for example). A solution
 *        would be always to return arrays with: local vars, global vars, thunks
 * - type management:
 *      + some bits of internal types are missing (like type casts and the address
 *        operator)
 *      + the type for an enum's value is always inferred as int (winedbg & dbghelp)
 *      + most of the code implies that sizeof(void*) = sizeof(int)
 *      + all computations should be made on long long
 *              o expr computations are in int:s
 *              o bitfield size is on a 4-bytes
 * - execution:
 *      + set a better fix for gdb (proxy mode) than the step-mode hack
 *      + implement function call in debuggee
 *      + trampoline management is broken when getting 16 <=> 32 thunk destination
 *        address
 *      + thunking of delayed imports doesn't work as expected (ie, when stepping,
 *        it currently stops at first insn with line number during the library 
 *        loading). We should identify this (__wine_delay_import) and set a
 *        breakpoint instead of single stepping the library loading.
 *      + it's wrong to copy thread->step_over_bp into process->bp[0] (when 
 *        we have a multi-thread debuggee). complete fix must include storing all
 *        thread's step-over bp in process-wide bp array, and not to handle bp
 *        when we have the wrong thread running into that bp
 *      + code in CREATE_PROCESS debug event doesn't work on Windows, as we cannot
 *        get the name of the main module this way. We should rewrite all this code
 *        and store in struct dbg_process as early as possible (before process
 *        creation or attachment), the name of the main module
 * - global:
 *      + define a better way to enable the wine extensions (either DBG SDK function
 *        in dbghelp, or TLS variable, or environment variable or ...)
 *      + audit all files to ensure that we check all potential return values from
 *        every function call to catch the errors
 *      + BTW check also whether the exception mechanism is the best way to return
 *        errors (or find a proper fix for MinGW port)
 */

WINE_DEFAULT_DEBUG_CHANNEL(winedbg);

struct dbg_process*	dbg_curr_process = NULL;
struct dbg_thread*	dbg_curr_thread = NULL;
DWORD_PTR	        dbg_curr_tid = 0;
DWORD_PTR	        dbg_curr_pid = 0;
CONTEXT                 dbg_context;
BOOL    	        dbg_interactiveP = FALSE;
HANDLE                  dbg_houtput = 0;

static struct list      dbg_process_list = LIST_INIT(dbg_process_list);

struct dbg_internal_var         dbg_internal_vars[DBG_IV_LAST];

static void dbg_outputA(const char* buffer, int len)
{
    static char line_buff[4096];
    static unsigned int line_pos;

    DWORD w, i;

    while (len > 0)
    {
        unsigned int count = min( len, sizeof(line_buff) - line_pos );
        memcpy( line_buff + line_pos, buffer, count );
        buffer += count;
        len -= count;
        line_pos += count;
        for (i = line_pos; i > 0; i--) if (line_buff[i-1] == '\n') break;
        if (!i)  /* no newline found */
        {
            if (len > 0) i = line_pos;  /* buffer is full, flush anyway */
            else break;
        }
        WriteFile(dbg_houtput, line_buff, i, &w, NULL);
        memmove( line_buff, line_buff + i, line_pos - i );
        line_pos -= i;
    }
}

const char* dbg_W2A(const WCHAR* buffer, unsigned len)
{
    static unsigned ansilen;
    static char* ansi;
    unsigned newlen;

    newlen = WideCharToMultiByte(CP_ACP, 0, buffer, len, NULL, 0, NULL, NULL);
    if (newlen > ansilen)
    {
        static char* newansi;
        if (ansi)
            newansi = HeapReAlloc(GetProcessHeap(), 0, ansi, newlen);
        else
            newansi = HeapAlloc(GetProcessHeap(), 0, newlen);
        if (!newansi) return NULL;
        ansilen = newlen;
        ansi = newansi;
    }
    WideCharToMultiByte(CP_ACP, 0, buffer, len, ansi, newlen, NULL, NULL);
    return ansi;
}

void	dbg_outputW(const WCHAR* buffer, int len)
{
    const char* ansi = dbg_W2A(buffer, len);
    if (ansi) dbg_outputA(ansi, strlen(ansi));
    /* FIXME: should CP_ACP be GetConsoleCP()? */
}

int	dbg_printf(const char* format, ...)
{
    static    char	buf[4*1024];
    va_list 	valist;
    int		len;

    va_start(valist, format);
    len = vsnprintf(buf, sizeof(buf), format, valist);
    va_end(valist);

    if (len <= -1 || len >= sizeof(buf)) 
    {
	len = sizeof(buf) - 1;
	buf[len] = 0;
	buf[len - 1] = buf[len - 2] = buf[len - 3] = '.';
    }
    dbg_outputA(buf, len);
    return len;
}

static	unsigned dbg_load_internal_vars(void)
{
    HKEY	                hkey;
    DWORD 	                type = REG_DWORD;
    DWORD	                val;
    DWORD 	                count = sizeof(val);
    int		                i;
    struct dbg_internal_var*    div = dbg_internal_vars;

/* initializes internal vars table */
#define  INTERNAL_VAR(_var,_val,_ref,_tid) 			\
        div->val = _val; div->name = #_var; div->pval = _ref;	\
        div->typeid = _tid; div++;
#include "intvar.h"
#undef   INTERNAL_VAR

    /* @@ Wine registry key: HKCU\Software\Wine\WineDbg */
    if (RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) 
    {
	WINE_ERR("Cannot create WineDbg key in registry\n");
	return FALSE;
    }

    for (i = 0; i < DBG_IV_LAST; i++) 
    {
        if (!dbg_internal_vars[i].pval) 
        {
            if (!RegQueryValueExA(hkey, dbg_internal_vars[i].name, 0,
                                  &type, (LPBYTE)&val, &count))
                dbg_internal_vars[i].val = val;
            dbg_internal_vars[i].pval = &dbg_internal_vars[i].val;
        }
    }
    RegCloseKey(hkey);

    return TRUE;
}

static	unsigned dbg_save_internal_vars(void)
{
    HKEY	                hkey;
    int		                i;

    /* @@ Wine registry key: HKCU\Software\Wine\WineDbg */
    if (RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) 
    {
	WINE_ERR("Cannot create WineDbg key in registry\n");
	return FALSE;
    }

    for (i = 0; i < DBG_IV_LAST; i++) 
    {
        /* FIXME: type should be inferred from basic type -if any- of intvar */
        if (dbg_internal_vars[i].pval == &dbg_internal_vars[i].val)
        {
            DWORD val = dbg_internal_vars[i].val;
            RegSetValueExA(hkey, dbg_internal_vars[i].name, 0, REG_DWORD, (BYTE *)&val, sizeof(val));
        }
    }
    RegCloseKey(hkey);
    return TRUE;
}

const struct dbg_internal_var* dbg_get_internal_var(const char* name)
{
    const struct dbg_internal_var*      div;

    for (div = &dbg_internal_vars[DBG_IV_LAST - 1]; div >= dbg_internal_vars; div--)
    {
	if (!strcmp(div->name, name)) return div;
    }
    for (div = be_cpu->context_vars; div->name; div++)
    {
	if (!strcasecmp(div->name, name))
        {
            struct dbg_internal_var*    ret = (void*)lexeme_alloc_size(sizeof(*ret));
            /* relocate register's field against current context */
            *ret = *div;
            ret->pval = (DWORD_PTR*)((char*)&dbg_context + (DWORD_PTR)div->pval);
            return ret;
        }
    }

    return NULL;
}

unsigned         dbg_num_processes(void)
{
    return list_count(&dbg_process_list);
}

struct dbg_process*     dbg_get_process(DWORD pid)
{
    struct dbg_process*	p;

    LIST_FOR_EACH_ENTRY(p, &dbg_process_list, struct dbg_process, entry)
	if (p->pid == pid) return p;
    return NULL;
}

struct dbg_process*     dbg_get_process_h(HANDLE h)
{
    struct dbg_process*	p;

    LIST_FOR_EACH_ENTRY(p, &dbg_process_list, struct dbg_process, entry)
	if (p->handle == h) return p;
    return NULL;
}

struct dbg_process*	dbg_add_process(const struct be_process_io* pio, DWORD pid, HANDLE h)
{
    struct dbg_process*	p;

    if ((p = dbg_get_process(pid)))
    {
        if (p->handle != 0)
        {
            WINE_ERR("Process (%04x) is already defined\n", pid);
        }
        else
        {
            p->handle = h;
            p->process_io = pio;
            p->imageName = NULL;
        }
        return p;
    }

    if (!(p = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_process)))) return NULL;
    p->handle = h;
    p->pid = pid;
    p->process_io = pio;
    p->pio_data = NULL;
    p->imageName = NULL;
    list_init(&p->threads);
    p->continue_on_first_exception = FALSE;
    p->active_debuggee = FALSE;
    p->next_bp = 1;  /* breakpoint 0 is reserved for step-over */
    memset(p->bp, 0, sizeof(p->bp));
    p->delayed_bp = NULL;
    p->num_delayed_bp = 0;
    p->source_ofiles = NULL;
    p->search_path = NULL;
    p->source_current_file[0] = '\0';
    p->source_start_line = -1;
    p->source_end_line = -1;

    list_add_head(&dbg_process_list, &p->entry);
    return p;
}

void dbg_set_process_name(struct dbg_process* p, const WCHAR* imageName)
{
    assert(p->imageName == NULL);
    if (imageName)
    {
        WCHAR* tmp = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(imageName) + 1) * sizeof(WCHAR));
        if (tmp) p->imageName = lstrcpyW(tmp, imageName);
    }
}

void dbg_del_process(struct dbg_process* p)
{
    struct dbg_thread*  t;
    struct dbg_thread*  t2;
    int	i;

    LIST_FOR_EACH_ENTRY_SAFE(t, t2, &p->threads, struct dbg_thread, entry)
        dbg_del_thread(t);

    for (i = 0; i < p->num_delayed_bp; i++)
        if (p->delayed_bp[i].is_symbol)
            HeapFree(GetProcessHeap(), 0, p->delayed_bp[i].u.symbol.name);

    HeapFree(GetProcessHeap(), 0, p->delayed_bp);
    source_nuke_path(p);
    source_free_files(p);
    list_remove(&p->entry);
    if (p == dbg_curr_process) dbg_curr_process = NULL;
    HeapFree(GetProcessHeap(), 0, (char*)p->imageName);
    HeapFree(GetProcessHeap(), 0, p);
}

/******************************************************************
 *		dbg_init
 *
 * Initializes the dbghelp library, and also sets the application directory
 * as a place holder for symbol searches.
 */
BOOL dbg_init(HANDLE hProc, const WCHAR* in, BOOL invade)
{
    BOOL        ret;

    ret = SymInitialize(hProc, NULL, invade);
    if (ret && in)
    {
        const WCHAR*    last;

        for (last = in + lstrlenW(in) - 1; last >= in; last--)
        {
            if (*last == '/' || *last == '\\')
            {
                WCHAR*  tmp;
                tmp = HeapAlloc(GetProcessHeap(), 0, (1024 + 1 + (last - in) + 1) * sizeof(WCHAR));
                if (tmp && SymGetSearchPathW(hProc, tmp, 1024))
                {
                    WCHAR*      x = tmp + lstrlenW(tmp);

                    *x++ = ';';
                    memcpy(x, in, (last - in) * sizeof(WCHAR));
                    x[last - in] = '\0';
                    ret = SymSetSearchPathW(hProc, tmp);
                }
                else ret = FALSE;
                HeapFree(GetProcessHeap(), 0, tmp);
                break;
            }
        }
    }
    return ret;
}

struct mod_loader_info
{
    HANDLE              handle;
    IMAGEHLP_MODULE64*  imh_mod;
};

static BOOL CALLBACK mod_loader_cb(PCSTR mod_name, DWORD64 base, PVOID ctx)
{
    struct mod_loader_info*     mli = ctx;

    if (!strcmp(mod_name, "<wine-loader>"))
    {
        if (SymGetModuleInfo64(mli->handle, base, mli->imh_mod))
            return FALSE; /* stop enum */
    }
    return TRUE;
}

BOOL dbg_get_debuggee_info(HANDLE hProcess, IMAGEHLP_MODULE64* imh_mod)
{
    struct mod_loader_info  mli;
    DWORD                   opt;

    /* this will resynchronize builtin dbghelp's internal ELF module list */
    SymLoadModule(hProcess, 0, 0, 0, 0, 0);
    mli.handle  = hProcess;
    mli.imh_mod = imh_mod;
    imh_mod->SizeOfStruct = sizeof(*imh_mod);
    imh_mod->BaseOfImage = 0;
    /* this is a wine specific options to return also ELF modules in the
     * enumeration
     */
    SymSetOptions((opt = SymGetOptions()) | 0x40000000);
    SymEnumerateModules64(hProcess, mod_loader_cb, (void*)&mli);
    SymSetOptions(opt);

    return imh_mod->BaseOfImage != 0;
}

BOOL dbg_load_module(HANDLE hProc, HANDLE hFile, const WCHAR* name, DWORD_PTR base, DWORD size)
{
    BOOL ret = SymLoadModuleExW(hProc, NULL, name, NULL, base, size, NULL, 0);
    if (ret)
    {
        IMAGEHLP_MODULEW64      ihm;
        ihm.SizeOfStruct = sizeof(ihm);
        if (SymGetModuleInfoW64(hProc, base, &ihm) && (ihm.PdbUnmatched || ihm.DbgUnmatched))
            dbg_printf("Loaded unmatched debug information for %s\n", wine_dbgstr_w(name));
    }
    return ret;
}

struct dbg_thread* dbg_get_thread(struct dbg_process* p, DWORD tid)
{
    struct dbg_thread*	t;

    if (!p) return NULL;
    LIST_FOR_EACH_ENTRY(t, &p->threads, struct dbg_thread, entry)
	if (t->tid == tid) return t;
    return NULL;
}

struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid,
                                  HANDLE h, void* teb)
{
    struct dbg_thread*	t = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_thread));

    if (!t)
	return NULL;

    t->handle = h;
    t->tid = tid;
    t->teb = teb;
    t->process = p;
    t->exec_mode = dbg_exec_cont;
    t->exec_count = 0;
    t->step_over_bp.enabled = FALSE;
    t->step_over_bp.refcount = 0;
    t->stopped_xpoint = -1;
    t->in_exception = FALSE;
    t->frames = NULL;
    t->num_frames = 0;
    t->curr_frame = -1;
    t->addr_mode = AddrModeFlat;

    snprintf(t->name, sizeof(t->name), "%04x", tid);

    list_add_head(&p->threads, &t->entry);

    return t;
}

void dbg_del_thread(struct dbg_thread* t)
{
    HeapFree(GetProcessHeap(), 0, t->frames);
    list_remove(&t->entry);
    if (t == dbg_curr_thread) dbg_curr_thread = NULL;
    HeapFree(GetProcessHeap(), 0, t);
}

void dbg_set_option(const char* option, const char* val)
{
    if (!strcasecmp(option, "module_load_mismatched"))
    {
        DWORD   opt = SymGetOptions();
        if (!val)
            dbg_printf("Option: module_load_mismatched %s\n", opt & SYMOPT_LOAD_ANYTHING ? "true" : "false");
        else if (!strcasecmp(val, "true"))      opt |= SYMOPT_LOAD_ANYTHING;
        else if (!strcasecmp(val, "false"))     opt &= ~SYMOPT_LOAD_ANYTHING;
        else
        {
            dbg_printf("Syntax: module_load_mismatched [true|false]\n");
            return;
        }
        SymSetOptions(opt);
    }
    else if (!strcasecmp(option, "symbol_picker"))
    {
        if (!val)
            dbg_printf("Option: symbol_picker %s\n",
                       symbol_current_picker == symbol_picker_interactive ? "interactive" : "scoped");
        else if (!strcasecmp(val, "interactive"))
            symbol_current_picker = symbol_picker_interactive;
        else if (!strcasecmp(val, "scoped"))
            symbol_current_picker = symbol_picker_scoped;
        else
        {
            dbg_printf("Syntax: symbol_picker [interactive|scoped]\n");
            return;
        }
    }
    else dbg_printf("Unknown option '%s'\n", option);
}

BOOL dbg_interrupt_debuggee(void)
{
    struct dbg_process* p;
    if (list_empty(&dbg_process_list)) return FALSE;
    /* FIXME: since we likely have a single process, signal the first process
     * in list
     */
    p = LIST_ENTRY(list_head(&dbg_process_list), struct dbg_process, entry);
    if (list_next(&dbg_process_list, &p->entry)) dbg_printf("Ctrl-C: only stopping the first process\n");
    else dbg_printf("Ctrl-C: stopping debuggee\n");
    p->continue_on_first_exception = FALSE;
    return DebugBreakProcess(p->handle);
}

static BOOL WINAPI ctrl_c_handler(DWORD dwCtrlType)
{
    if (dwCtrlType == CTRL_C_EVENT)
    {
        return dbg_interrupt_debuggee();
    }
    return FALSE;
}

void dbg_init_console(void)
{
    /* set the output handle */
    dbg_houtput = GetStdHandle(STD_OUTPUT_HANDLE);

    /* set our control-C handler */
    SetConsoleCtrlHandler(ctrl_c_handler, TRUE);

    /* set our own title */
    SetConsoleTitleA("Wine Debugger");
}

static int dbg_winedbg_usage(BOOL advanced)
{
    if (advanced)
    {
    dbg_printf("Usage:\n"
               "   winedbg cmdline         launch process 'cmdline' (as if you were starting\n"
               "                           it with wine) and run WineDbg on it\n"
               "   winedbg <num>           attach to running process of pid <num> and run\n"
               "                           WineDbg on it\n"
               "   winedbg --gdb cmdline   launch process 'cmdline' (as if you were starting\n"
               "                           wine) and run gdb (proxied) on it\n"
               "   winedbg --gdb <num>     attach to running process of pid <num> and run\n"
               "                           gdb (proxied) on it\n"
               "   winedbg file.mdmp       reload the minidump file.mdmp into memory and run\n"
               "                           WineDbg on it\n"
               "   winedbg --help          prints advanced options\n");
    }
    else
        dbg_printf("Usage:\n\twinedbg [ [ --gdb ] [ prog-name [ prog-args ] | <num> | file.mdmp | --help ]\n");
    return 0;
}

void dbg_start_interactive(HANDLE hFile)
{
    struct dbg_process* p;
    struct dbg_process* p2;

    if (dbg_curr_process)
    {
        dbg_printf("WineDbg starting on pid %04lx\n", dbg_curr_pid);
        if (dbg_curr_process->active_debuggee) dbg_active_wait_for_first_exception();
    }

    dbg_interactiveP = TRUE;
    parser_handle(hFile);

    LIST_FOR_EACH_ENTRY_SAFE(p, p2, &dbg_process_list, struct dbg_process, entry)
        p->process_io->close_process(p, FALSE);

    dbg_save_internal_vars();
}

static LONG CALLBACK top_filter( EXCEPTION_POINTERS *ptr )
{
    dbg_printf( "winedbg: Internal crash at %p\n", ptr->ExceptionRecord->ExceptionAddress );
    return EXCEPTION_EXECUTE_HANDLER;
}

struct backend_cpu* be_cpu;
#ifdef __i386__
extern struct backend_cpu be_i386;
#elif defined(__powerpc__)
extern struct backend_cpu be_ppc;
#elif defined(__x86_64__)
extern struct backend_cpu be_x86_64;
#elif defined(__sparc__)
extern struct backend_cpu be_sparc;
#elif defined(__arm__)
extern struct backend_cpu be_arm;
#else
# error CPU unknown
#endif

int main(int argc, char** argv)
{
    int 	        retv = 0;
    HANDLE              hFile = INVALID_HANDLE_VALUE;
    enum dbg_start      ds;

#ifdef __i386__
    be_cpu = &be_i386;
#elif defined(__powerpc__)
    be_cpu = &be_ppc;
#elif defined(__x86_64__)
    be_cpu = &be_x86_64;
#elif defined(__sparc__)
    be_cpu = &be_sparc;
#elif defined(__arm__)
    be_cpu = &be_arm;
#else
# error CPU unknown
#endif
    /* Initialize the output */
    dbg_houtput = GetStdHandle(STD_OUTPUT_HANDLE);

    SetUnhandledExceptionFilter( top_filter );

    /* Initialize internal vars */
    if (!dbg_load_internal_vars()) return -1;

    /* as we don't care about exec name */
    argc--; argv++;

    if (argc && !strcmp(argv[0], "--help"))
        return dbg_winedbg_usage(TRUE);

    if (argc && !strcmp(argv[0], "--gdb"))
    {
        retv = gdb_main(argc, argv);
        if (retv == -1) dbg_winedbg_usage(FALSE);
        return retv;
    }
    dbg_init_console();

    SymSetOptions((SymGetOptions() & ~(SYMOPT_UNDNAME)) |
                  SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS | SYMOPT_AUTO_PUBLICS);

    if (argc && !strcmp(argv[0], "--auto"))
    {
        switch (dbg_active_auto(argc, argv))
        {
        case start_ok:          return 0;
        case start_error_parse: return dbg_winedbg_usage(FALSE);
        case start_error_init:  return -1;
        }
    }
    if (argc && !strcmp(argv[0], "--minidump"))
    {
        switch (dbg_active_minidump(argc, argv))
        {
        case start_ok:          return 0;
        case start_error_parse: return dbg_winedbg_usage(FALSE);
        case start_error_init:  return -1;
        }
    }
    /* parse options */
    while (argc > 0 && argv[0][0] == '-')
    {
        if (!strcmp(argv[0], "--command"))
        {
            argc--; argv++;
            hFile = parser_generate_command_file(argv[0], NULL);
            if (hFile == INVALID_HANDLE_VALUE)
            {
                dbg_printf("Couldn't open temp file (%u)\n", GetLastError());
                return 1;
            }
            argc--; argv++;
            continue;
        }
        if (!strcmp(argv[0], "--file"))
        {
            argc--; argv++;
            hFile = CreateFileA(argv[0], GENERIC_READ|DELETE, 0, 
                                NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
            if (hFile == INVALID_HANDLE_VALUE)
            {
                dbg_printf("Couldn't open file %s (%u)\n", argv[0], GetLastError());
                return 1;
            }
            argc--; argv++;
            continue;
        }
        if (!strcmp(argv[0], "--"))
        {
            argc--; argv++;
            break;
        }
        return dbg_winedbg_usage(FALSE);
    }
    if (!argc) ds = start_ok;
    else if ((ds = dbg_active_attach(argc, argv)) == start_error_parse &&
             (ds = minidump_reload(argc, argv)) == start_error_parse)
        ds = dbg_active_launch(argc, argv);
    switch (ds)
    {
    case start_ok:              break;
    case start_error_parse:     return dbg_winedbg_usage(FALSE);
    case start_error_init:      return -1;
    }

    dbg_start_interactive(hFile);

    return 0;
}
