Pith - fireworks_wine_drag_fix
/* fireworks cs6 wine drag fix */
/* vgmlr and opus 5.5 */

#include <windows.h>
#include <tlhelp32.h>
#include <wchar.h>

static WCHAR *skip_arg0(WCHAR *p)
{
    if (*p == L'"') {
        p++;
        while (*p && *p != L'"') p++;
        if (*p) p++;
    } else {
        while (*p && *p != L' ' && *p != L'\t') p++;
    }
    while (*p == L' ' || *p == L'\t') p++;
    return p;
}

static void *remote_loadlib(DWORD pid)
{
    HMODULE k32 = GetModuleHandleW(L"kernel32.dll");
    BYTE *local = (BYTE *)GetProcAddress(k32, "LoadLibraryW");
    MODULEENTRY32W me = { sizeof(me) };
    HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
    void *res = local;

    if (snap == INVALID_HANDLE_VALUE) return res;
    if (Module32FirstW(snap, &me)) do {
        if (!lstrcmpiW(me.szModule, L"kernel32.dll")) {
            res = me.modBaseAddr + (local - (BYTE *)k32);
            break;
        }
    } while (Module32NextW(snap, &me));
    CloseHandle(snap);
    return res;
}

static void fail(const WCHAR *what)
{
    WCHAR buf[256];
    wsprintfW(buf, L"%s failed (%lu)", what, GetLastError());
    MessageBoxW(NULL, buf, L"fwlaunch", MB_ICONERROR);
}

int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cl, int show)
{
    static WCHAR dir[MAX_PATH], exe[MAX_PATH], dll[MAX_PATH], cmd[32768];
    STARTUPINFOW si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    WCHAR *slash;
    SIZE_T size;
    void *mem;
    HANDLE th;
    DWORD code = 0;

    GetModuleFileNameW(NULL, dir, MAX_PATH);
    slash = wcsrchr(dir, L'\\');
    if (slash) slash[1] = 0;
    lstrcpyW(exe, dir); lstrcatW(exe, L"Fireworks.exe");
    lstrcpyW(dll, dir); lstrcatW(dll, L"fwshim.dll");

    lstrcpyW(cmd, L"\"");
    lstrcatW(cmd, exe);
    lstrcatW(cmd, L"\" ");
    lstrcatW(cmd, skip_arg0(GetCommandLineW()));

    if (!CreateProcessW(exe, cmd, NULL, NULL, FALSE, 0, NULL, dir, &si, &pi)) {
        fail(L"CreateProcess");
        return 1;
    }
    WaitForInputIdle(pi.hProcess, 30000);

    size = (lstrlenW(dll) + 1) * sizeof(WCHAR);
    mem = VirtualAllocEx(pi.hProcess, NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (!mem || !WriteProcessMemory(pi.hProcess, mem, dll, size, NULL)) {
        fail(L"WriteProcessMemory");
        return 1;
    }
    th = CreateRemoteThread(pi.hProcess, NULL, 0,
        (LPTHREAD_START_ROUTINE)remote_loadlib(pi.dwProcessId), mem, 0, NULL);
    if (!th) {
        fail(L"CreateRemoteThread");
        return 1;
    }
    WaitForSingleObject(th, 15000);
    GetExitCodeThread(th, &code);
    if (!code) MessageBoxW(NULL, L"fwshim.dll not loaded", L"fwlaunch", MB_ICONERROR);

    CloseHandle(th);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    return 0;
}