/*
 * Wine debugger utility routines
 *
 * Copyright 1993 Eric Youngdale
 * Copyright 1995 Alexandre Julliard
 *
 * 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#include "debugger.h"
#include "wingdi.h"
#include "winuser.h"
#include "tlhelp32.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winedbg);

/***********************************************************************
 *           print_help
 *
 * Implementation of the 'help' command.
 */
void print_help(void)
{
    int i = 0;
    static const char * const helptext[] =
        {
            "The commands accepted by the Wine debugger are a reasonable",
            "subset of the commands that gdb accepts.",
            "The commands currently are:",
            "  help                                   quit",
            "  break [*<addr>]                        watch | rwatch *<addr>",
            "  delete break bpnum                     disable bpnum",
            "  enable bpnum                           condition <bpnum> [<expr>]",
            "  finish                                 cont [N]",
            "  step [N]                               next [N]",
            "  stepi [N]                              nexti [N]",
            "  x <addr>                               print <expr>",
            "  display <expr>                         undisplay <disnum>",
            "  local display <expr>                   delete display <disnum>",                  
            "  enable display <disnum>                disable display <disnum>",
            "  bt [<tid>|all]                         frame <n>",
            "  up                                     down",
            "  list <lines>                           disassemble [<addr>][,<addr>]",
            "  show dir                               dir <path>",
            "  set <reg> = <expr>                     set *<addr> = <expr>",
            "  pass                                   whatis",
            "  info (see 'help info' for options)",

            "The 'x' command accepts repeat counts and formats (including 'i') in the",
            "same way that gdb does.\n",

            "The following are examples of legal expressions:",
            " $eax     $eax+0x3   0x1000   ($eip + 256)  *$eax   *($esp + 3)",
            " Also, a nm format symbol table can be read from a file using the",
            " symbolfile command.", /*  Symbols can also be defined individually with",
                                        " the define command.", */
            "",
            NULL
        };

    while (helptext[i]) dbg_printf("%s\n", helptext[i++]);
}


/***********************************************************************
 *           info_help
 *
 * Implementation of the 'help info' command.
 */
void info_help(void)
{
    int i = 0;
    static const char * const infotext[] =
        {
            "The info commands allow you to get assorted bits of interesting stuff",
            "to be displayed.  The options are:",
            "  info break           Displays information about breakpoints",
            "  info class <name>    Displays information about window class <name>",
            "  info display         Shows auto-display expressions in use",
            "  info except <pid>    Shows exception handler chain (in a given process)",
            "  info locals          Displays values of all local vars for current frame",
            "  info maps <pid>      Shows virtual mappings (in a given process)",
            "  info process         Shows all running processes",
            "  info reg             Displays values of the general registers at top of stack",
            "  info all-reg         Displays the general and floating point registers",
            "  info segments <pid>  Displays information about all known segments",
            "  info share           Displays all loaded modules",
            "  info share <addr>    Displays internal module state",
            "  info stack [<len>]   Dumps information about top of stack, up to len words",
            "  info symbol <sym>    Displays information about a given symbol",
            "  info thread          Shows all running threads",
            "  info wnd <handle>    Displays internal window state",
            "",
            NULL
        };

    while (infotext[i]) dbg_printf("%s\n", infotext[i++]);
}

static const char* get_symtype_str(const IMAGEHLP_MODULE64* mi)
{
    switch (mi->SymType)
    {
    default:
    case SymNone:       return "--none--";
    case SymCoff:       return "COFF";
    case SymCv:         return "CodeView";
    case SymPdb:        return "PDB";
    case SymExport:     return "Export";
    case SymDeferred:   return "Deferred";
    case SymSym:        return "Sym";
    case SymDia:
        switch (mi->CVSig)
        {
        case 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24):
            return "Stabs";
        case 'D' | ('W' << 8) | ('A' << 16) | ('R' << 24):
            return "Dwarf";
        default:
            return "DIA";

        }
    }
}

struct info_module
{
    IMAGEHLP_MODULE64*  mi;
    unsigned            num_alloc;
    unsigned            num_used;
};

static void module_print_info(const IMAGEHLP_MODULE64* mi, BOOL is_embedded)
{
    dbg_printf("%*.*s-%*.*s\t%-16s%s\n",
               ADDRWIDTH, ADDRWIDTH, wine_dbgstr_longlong(mi->BaseOfImage),
               ADDRWIDTH, ADDRWIDTH, wine_dbgstr_longlong(mi->BaseOfImage + mi->ImageSize),
               is_embedded ? "\\" : get_symtype_str(mi), mi->ModuleName);
}

static int      module_compare(const void* p1, const void* p2)
{
    LONGLONG val = ((const IMAGEHLP_MODULE64*)p1)->BaseOfImage -
        ((const IMAGEHLP_MODULE64*)p2)->BaseOfImage;
    if (val < 0) return -1;
    else if (val > 0) return 1;
    else return 0;
}

static inline BOOL module_is_container(const IMAGEHLP_MODULE64* wmod_cntnr,
                                       const IMAGEHLP_MODULE64* wmod_child)
{
    return wmod_cntnr->BaseOfImage <= wmod_child->BaseOfImage &&
        wmod_cntnr->BaseOfImage + wmod_cntnr->ImageSize >=
        wmod_child->BaseOfImage + wmod_child->ImageSize;
}

static BOOL CALLBACK info_mod_cb(PCSTR mod_name, DWORD64 base, PVOID ctx)
{
    struct info_module* im = ctx;

    if (im->num_used + 1 > im->num_alloc)
    {
        im->num_alloc += 16;
        im->mi = dbg_heap_realloc(im->mi, im->num_alloc * sizeof(*im->mi));
    }
    im->mi[im->num_used].SizeOfStruct = sizeof(im->mi[im->num_used]);
    if (SymGetModuleInfo64(dbg_curr_process->handle, base, &im->mi[im->num_used]))
    {
        im->num_used++;
    }   
    return TRUE;
}

/***********************************************************************
 *           info_win32_module
 *
 * Display information about a given module (DLL or EXE), or about all modules
 */
void info_win32_module(DWORD64 base)
{
    struct info_module  im;
    UINT                i, j, num_printed = 0;
    DWORD               opt;

    if (!dbg_curr_process)
    {
        dbg_printf("Cannot get info on module while no process is loaded\n");
        return;
    }

    im.mi = NULL;
    im.num_alloc = im.num_used = 0;

    /* this is a wine specific options to return also ELF modules in the
     * enumeration
     */
    SymSetOptions((opt = SymGetOptions()) | 0x40000000);
    SymEnumerateModules64(dbg_curr_process->handle, info_mod_cb, (void*)&im);
    SymSetOptions(opt);

    qsort(im.mi, im.num_used, sizeof(im.mi[0]), module_compare);

    dbg_printf("Module\tAddress\t\t\t%sDebug info\tName (%d modules)\n",
	       ADDRWIDTH == 16 ? "\t\t" : "", im.num_used);

    for (i = 0; i < im.num_used; i++)
    {
        if (base && 
            (base < im.mi[i].BaseOfImage || base >= im.mi[i].BaseOfImage + im.mi[i].ImageSize))
            continue;
        if (strstr(im.mi[i].ModuleName, "<elf>"))
        {
            dbg_printf("ELF\t");
            module_print_info(&im.mi[i], FALSE);
            /* print all modules embedded in this one */
            for (j = 0; j < im.num_used; j++)
            {
                if (!strstr(im.mi[j].ModuleName, "<elf>") && module_is_container(&im.mi[i], &im.mi[j]))
                {
                    dbg_printf("  \\-PE\t");
                    module_print_info(&im.mi[j], TRUE);
                }
            }
        }
        else
        {
            /* check module is not embedded in another module */
            for (j = 0; j < im.num_used; j++) 
            {
                if (strstr(im.mi[j].ModuleName, "<elf>") && module_is_container(&im.mi[j], &im.mi[i]))
                    break;
            }
            if (j < im.num_used) continue;
            if (strstr(im.mi[i].ModuleName, ".so") || strchr(im.mi[i].ModuleName, '<'))
                dbg_printf("ELF\t");
            else
                dbg_printf("PE\t");
            module_print_info(&im.mi[i], FALSE);
        }
        num_printed++;
    }
    HeapFree(GetProcessHeap(), 0, im.mi);

    if (base && !num_printed)
        dbg_printf("'0x%x%08x' is not a valid module address\n", (DWORD)(base >> 32), (DWORD)base);
}

struct class_walker
{
    ATOM*	table;
    int		used;
    int		alloc;
};

static void class_walker(HWND hWnd, struct class_walker* cw)
{
    char	clsName[128];
    int	        i;
    ATOM	atom;
    HWND	child;

    if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
        return;
    if ((atom = FindAtomA(clsName)) == 0)
        return;

    for (i = 0; i < cw->used; i++)
    {
        if (cw->table[i] == atom)
            break;
    }
    if (i == cw->used)
    {
        if (cw->used >= cw->alloc)
        {
            cw->alloc += 16;
            cw->table = dbg_heap_realloc(cw->table, cw->alloc * sizeof(ATOM));
        }
        cw->table[cw->used++] = atom;
        info_win32_class(hWnd, clsName);
    }
    do
    {
        if ((child = GetWindow(hWnd, GW_CHILD)) != 0)
            class_walker(child, cw);
    } while ((hWnd = GetWindow(hWnd, GW_HWNDNEXT)) != 0);
}

void info_win32_class(HWND hWnd, const char* name)
{
    WNDCLASSEXA	wca;
    HINSTANCE   hInst = hWnd ? (HINSTANCE)GetWindowLongPtrW(hWnd, GWLP_HINSTANCE) : 0;

    if (!name)
    {
        struct class_walker cw;

        cw.table = NULL;
        cw.used = cw.alloc = 0;
        class_walker(GetDesktopWindow(), &cw);
        HeapFree(GetProcessHeap(), 0, cw.table);
        return;
    }

    if (!GetClassInfoExA(hInst, name, &wca))
    {
        dbg_printf("Cannot find class '%s'\n", name);
        return;
    }

    dbg_printf("Class '%s':\n", name);
    dbg_printf("style=0x%08x  wndProc=%p\n"
               "inst=%p  icon=%p  cursor=%p  bkgnd=%p\n"
               "clsExtra=%d  winExtra=%d\n",
               wca.style, wca.lpfnWndProc, wca.hInstance,
               wca.hIcon, wca.hCursor, wca.hbrBackground,
               wca.cbClsExtra, wca.cbWndExtra);

    if (hWnd && wca.cbClsExtra)
    {
        int		i;
        WORD		w;

        dbg_printf("Extra bytes:");
        for (i = 0; i < wca.cbClsExtra / 2; i++)
        {
            w = GetClassWord(hWnd, i * 2);
            /* FIXME: depends on i386 endian-ity */
            dbg_printf(" %02x %02x", HIBYTE(w), LOBYTE(w));
        }
        dbg_printf("\n");
    }
    dbg_printf("\n");
    /* FIXME:
     * + print #windows (or even list of windows...)
     * + print extra bytes => this requires a window handle on this very class...
     */
}

static void info_window(HWND hWnd, int indent)
{
    char	clsName[128];
    char	wndName[128];
    HWND	child;

    do
    {
        if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
            strcpy(clsName, "-- Unknown --");
        if (!GetWindowTextA(hWnd, wndName, sizeof(wndName)))
            strcpy(wndName, "-- Empty --");

        dbg_printf("%*s%08lx%*s %-17.17s %08x %0*lx %08x %.14s\n",
                   indent, "", (DWORD_PTR)hWnd, 12 - indent, "",
                   clsName, GetWindowLongW(hWnd, GWL_STYLE),
                   ADDRWIDTH, (ULONG_PTR)GetWindowLongPtrW(hWnd, GWLP_WNDPROC),
                   GetWindowThreadProcessId(hWnd, NULL), wndName);

        if ((child = GetWindow(hWnd, GW_CHILD)) != 0)
            info_window(child, indent + 1);
    } while ((hWnd = GetWindow(hWnd, GW_HWNDNEXT)) != 0);
}

void info_win32_window(HWND hWnd, BOOL detailed)
{
    char	clsName[128];
    char	wndName[128];
    RECT	clientRect;
    RECT	windowRect;
    WORD	w;

    if (!IsWindow(hWnd)) hWnd = GetDesktopWindow();

    if (!detailed)
    {
        dbg_printf("%-20.20s %-17.17s %-8.8s %-*.*s %-8.8s %s\n",
                   "Window handle", "Class Name", "Style",
		   ADDRWIDTH, ADDRWIDTH, "WndProc", "Thread", "Text");
        info_window(hWnd, 0);
        return;
    }

    if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
        strcpy(clsName, "-- Unknown --");
    if (!GetWindowTextA(hWnd, wndName, sizeof(wndName)))
        strcpy(wndName, "-- Empty --");
    if (!GetClientRect(hWnd, &clientRect) || 
        !MapWindowPoints(hWnd, 0, (LPPOINT) &clientRect, 2))
        SetRectEmpty(&clientRect);
    if (!GetWindowRect(hWnd, &windowRect))
        SetRectEmpty(&windowRect);

    /* FIXME missing fields: hmemTaskQ, hrgnUpdate, dce, flags, pProp, scroll */
    dbg_printf("next=%p  child=%p  parent=%p  owner=%p  class='%s'\n"
               "inst=%p  active=%p  idmenu=%08lx\n"
               "style=0x%08x  exstyle=0x%08x  wndproc=%p  text='%s'\n"
               "client=%d,%d-%d,%d  window=%d,%d-%d,%d sysmenu=%p\n",
               GetWindow(hWnd, GW_HWNDNEXT),
               GetWindow(hWnd, GW_CHILD),
               GetParent(hWnd),
               GetWindow(hWnd, GW_OWNER),
               clsName,
               (HINSTANCE)GetWindowLongPtrW(hWnd, GWLP_HINSTANCE),
               GetLastActivePopup(hWnd),
               (ULONG_PTR)GetWindowLongPtrW(hWnd, GWLP_ID),
               GetWindowLongW(hWnd, GWL_STYLE),
               GetWindowLongW(hWnd, GWL_EXSTYLE),
               (void*)GetWindowLongPtrW(hWnd, GWLP_WNDPROC),
               wndName,
               clientRect.left, clientRect.top, clientRect.right, clientRect.bottom,
               windowRect.left, windowRect.top, windowRect.right, windowRect.bottom,
               GetSystemMenu(hWnd, FALSE));

    if (GetClassLongW(hWnd, GCL_CBWNDEXTRA))
    {
        UINT i;

        dbg_printf("Extra bytes:");
        for (i = 0; i < GetClassLongW(hWnd, GCL_CBWNDEXTRA) / 2; i++)
        {
            w = GetWindowWord(hWnd, i * 2);
            /* FIXME: depends on i386 endian-ity */
            dbg_printf(" %02x %02x", HIBYTE(w), LOBYTE(w));
	}
        dbg_printf("\n");
    }
    dbg_printf("\n");
}

void info_win32_processes(void)
{
    HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snap != INVALID_HANDLE_VALUE)
    {
        PROCESSENTRY32  entry;
        DWORD           current = dbg_curr_process ? dbg_curr_process->pid : 0;
        BOOL            ok;

        entry.dwSize = sizeof(entry);
        ok = Process32First(snap, &entry);

        dbg_printf(" %-8.8s %-8.8s %-8.8s %s (all id:s are in hex)\n",
                   "pid", "threads", "parent", "executable");
        while (ok)
        {
            if (entry.th32ProcessID != GetCurrentProcessId())
                dbg_printf("%c%08x %-8d %08x '%s'\n",
                           (entry.th32ProcessID == current) ? '>' : ' ',
                           entry.th32ProcessID, entry.cntThreads,
                           entry.th32ParentProcessID, entry.szExeFile);
            ok = Process32Next(snap, &entry);
        }
        CloseHandle(snap);
    }
}

static BOOL get_process_name(DWORD pid, PROCESSENTRY32* entry)
{
    BOOL   ret = FALSE;
    HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (snap != INVALID_HANDLE_VALUE)
    {
        entry->dwSize = sizeof(*entry);
        if (Process32First(snap, entry))
            while (!(ret = (entry->th32ProcessID == pid)) &&
                   Process32Next(snap, entry));
        CloseHandle(snap);
    }
    return ret;
}

void info_win32_threads(void)
{
    HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (snap != INVALID_HANDLE_VALUE)
    {
        THREADENTRY32	entry;
        BOOL 		ok;
	DWORD		lastProcessId = 0;

	entry.dwSize = sizeof(entry);
	ok = Thread32First(snap, &entry);

        dbg_printf("%-8.8s %-8.8s %s (all id:s are in hex)\n",
                   "process", "tid", "prio");
        while (ok)
        {
            if (entry.th32OwnerProcessID != GetCurrentProcessId())
	    {
		/* FIXME: this assumes that, in the snapshot, all threads of a same process are
		 * listed sequentially, which is not specified in the doc (Wine's implementation
		 * does it)
		 */
		if (entry.th32OwnerProcessID != lastProcessId)
		{
		    struct dbg_process*	p = dbg_get_process(entry.th32OwnerProcessID);
                    PROCESSENTRY32 pcs_entry;
                    const char* exename;

                    if (p)
                        exename = dbg_W2A(p->imageName, -1);
                    else if (get_process_name(entry.th32OwnerProcessID, &pcs_entry))
                        exename = pcs_entry.szExeFile;
                    else
                        exename = "";

		    dbg_printf("%08x%s %s\n",
                               entry.th32OwnerProcessID, p ? " (D)" : "", exename);
                    lastProcessId = entry.th32OwnerProcessID;
		}
                dbg_printf("\t%08x %4d%s\n",
                           entry.th32ThreadID, entry.tpBasePri,
                           (entry.th32ThreadID == dbg_curr_tid) ? " <==" : "");

	    }
            ok = Thread32Next(snap, &entry);
        }

        CloseHandle(snap);
    }
}

/***********************************************************************
 *           info_win32_exceptions
 *
 * Get info on the exception frames of a given thread.
 */
void info_win32_exceptions(DWORD tid)
{
    struct dbg_thread*  thread;
    void*               next_frame;

    if (!dbg_curr_process || !dbg_curr_thread)
    {
        dbg_printf("Cannot get info on exceptions while no process is loaded\n");
        return;
    }

    dbg_printf("Exception frames:\n");

    if (tid == dbg_curr_tid) thread = dbg_curr_thread;
    else
    {
        thread = dbg_get_thread(dbg_curr_process, tid);

        if (!thread)
        {
            dbg_printf("Unknown thread id (%04x) in current process\n", tid);
            return;
        }
        if (SuspendThread(thread->handle) == -1)
        {
            dbg_printf("Can't suspend thread id (%04x)\n", tid);
            return;
        }
    }

    if (!dbg_read_memory(thread->teb, &next_frame, sizeof(next_frame)))
    {
        dbg_printf("Can't read TEB:except_frame\n");
        return;
    }

    while (next_frame != (void*)-1)
    {
        EXCEPTION_REGISTRATION_RECORD frame;

        dbg_printf("%p: ", next_frame);
        if (!dbg_read_memory(next_frame, &frame, sizeof(frame)))
        {
            dbg_printf("Invalid frame address\n");
            break;
        }
        dbg_printf("prev=%p handler=%p\n", frame.Prev, frame.Handler);
        next_frame = frame.Prev;
    }

    if (tid != dbg_curr_tid) ResumeThread(thread->handle);
}

void info_win32_segments(DWORD start, int length)
{
    char 	flags[3];
    DWORD 	i;
    LDT_ENTRY	le;

    if (length == -1) length = (8192 - start);

    for (i = start; i < start + length; i++)
    {
        if (!dbg_curr_process->process_io->get_selector(dbg_curr_thread->handle, (i << 3) | 7, &le))
            continue;

        if (le.HighWord.Bits.Type & 0x08)
        {
            flags[0] = (le.HighWord.Bits.Type & 0x2) ? 'r' : '-';
            flags[1] = '-';
            flags[2] = 'x';
        }
        else
        {
            flags[0] = 'r';
            flags[1] = (le.HighWord.Bits.Type & 0x2) ? 'w' : '-';
            flags[2] = '-';
        }
        dbg_printf("%04x: sel=%04x base=%08x limit=%08x %d-bit %c%c%c\n",
                   i, (i << 3) | 7,
                   (le.HighWord.Bits.BaseHi << 24) +
                   (le.HighWord.Bits.BaseMid << 16) + le.BaseLow,
                   ((le.HighWord.Bits.LimitHi << 8) + le.LimitLow) <<
                   (le.HighWord.Bits.Granularity ? 12 : 0),
                   le.HighWord.Bits.Default_Big ? 32 : 16,
                   flags[0], flags[1], flags[2]);
    }
}

void info_win32_virtual(DWORD pid)
{
    MEMORY_BASIC_INFORMATION    mbi;
    char*                       addr = 0;
    const char*                 state;
    const char*                 type;
    char                        prot[3+1];
    HANDLE                      hProc;

    if (pid == dbg_curr_pid)
    {
        if (dbg_curr_process == NULL)
        {
            dbg_printf("Cannot look at mapping of current process, while no process is loaded\n");
            return;
        }
        hProc = dbg_curr_process->handle;
    }
    else
    {
        hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
        if (hProc == NULL)
        {
            dbg_printf("Cannot open process <%04x>\n", pid);
            return;
        }
    }

    dbg_printf("Address  End      State   Type    RWX\n");

    while (VirtualQueryEx(hProc, addr, &mbi, sizeof(mbi)) >= sizeof(mbi))
    {
        switch (mbi.State)
        {
        case MEM_COMMIT:        state = "commit "; break;
        case MEM_FREE:          state = "free   "; break;
        case MEM_RESERVE:       state = "reserve"; break;
        default:                state = "???    "; break;
        }
        if (mbi.State != MEM_FREE)
        {
            switch (mbi.Type)
            {
            case MEM_IMAGE:         type = "image  "; break;
            case MEM_MAPPED:        type = "mapped "; break;
            case MEM_PRIVATE:       type = "private"; break;
            case 0:                 type = "       "; break;
            default:                type = "???    "; break;
            }
            memset(prot, ' ' , sizeof(prot) - 1);
            prot[sizeof(prot) - 1] = '\0';
            if (mbi.AllocationProtect & (PAGE_READONLY|PAGE_READWRITE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))
                prot[0] = 'R';
            if (mbi.AllocationProtect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE))
                prot[1] = 'W';
            if (mbi.AllocationProtect & (PAGE_WRITECOPY|PAGE_EXECUTE_WRITECOPY))
                prot[1] = 'C';
            if (mbi.AllocationProtect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))
                prot[2] = 'X';
        }
        else
        {
            type = "";
            prot[0] = '\0';
        }
        dbg_printf("%08lx %08lx %s %s %s\n",
                   (DWORD_PTR)addr, (DWORD_PTR)addr + mbi.RegionSize - 1, state, type, prot);
        if (addr + mbi.RegionSize < addr) /* wrap around ? */
            break;
        addr += mbi.RegionSize;
    }
    if (pid != dbg_curr_pid) CloseHandle(hProc);
}

void info_wine_dbg_channel(BOOL turn_on, const char* cls, const char* name)
{
    struct dbg_lvalue           lvalue;
    struct __wine_debug_channel channel;
    unsigned char               mask;
    int                         done = 0;
    BOOL                        bAll;
    void*                       addr;

    if (!dbg_curr_process || !dbg_curr_thread)
    {
        dbg_printf("Cannot set/get debug channels while no process is loaded\n");
        return;
    }

    if (symbol_get_lvalue("debug_options", -1, &lvalue, FALSE) != sglv_found)
    {
        return;
    }
    addr = memory_to_linear_addr(&lvalue.addr);

    if (!cls)                          mask = ~0;
    else if (!strcmp(cls, "fixme"))    mask = (1 << __WINE_DBCL_FIXME);
    else if (!strcmp(cls, "err"))      mask = (1 << __WINE_DBCL_ERR);
    else if (!strcmp(cls, "warn"))     mask = (1 << __WINE_DBCL_WARN);
    else if (!strcmp(cls, "trace"))    mask = (1 << __WINE_DBCL_TRACE);
    else
    {
        dbg_printf("Unknown debug class %s\n", cls);
        return;
    }

    bAll = !strcmp("all", name);
    while (addr && dbg_read_memory(addr, &channel, sizeof(channel)))
    {
        if (!channel.name[0]) break;
        if (bAll || !strcmp( channel.name, name ))
        {
            if (turn_on) channel.flags |= mask;
            else channel.flags &= ~mask;
            if (dbg_write_memory(addr, &channel, sizeof(channel))) done++;
        }
        addr = (struct __wine_debug_channel *)addr + 1;
    }
    if (!done) dbg_printf("Unable to find debug channel %s\n", name);
    else WINE_TRACE("Changed %d channel instances\n", done);
}
