/*
 * Helper program for killing lingering python[_d].exe processes before
 * building, thus attempting to avoid build failures due to files being
 * locked.
 */

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

#pragma comment(lib, "psapi")

#ifdef _DEBUG
#define PYTHON_EXE          (L"python_d.exe")
#define PYTHON_EXE_LEN      (12)
#define KILL_PYTHON_EXE     (L"kill_python_d.exe")
#define KILL_PYTHON_EXE_LEN (17)
#else
#define PYTHON_EXE          (L"python.exe")
#define PYTHON_EXE_LEN      (10)
#define KILL_PYTHON_EXE     (L"kill_python.exe")
#define KILL_PYTHON_EXE_LEN (15)
#endif

int
main(int argc, char **argv)
{
    HANDLE   hp, hsp, hsm; /* process, snapshot processes, snapshot modules */
    DWORD    dac, our_pid;
    size_t   len;
    wchar_t  path[MAX_PATH+1];

    MODULEENTRY32W  me;
    PROCESSENTRY32W pe;

    me.dwSize = sizeof(MODULEENTRY32W);
    pe.dwSize = sizeof(PROCESSENTRY32W);

    memset(path, 0, MAX_PATH+1);

    our_pid = GetCurrentProcessId();

    hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid);
    if (hsm == INVALID_HANDLE_VALUE) {
        printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError());
        return 1;
    }

    if (!Module32FirstW(hsm, &me)) {
        printf("Module32FirstW[1] failed: %d\n", GetLastError());
        CloseHandle(hsm);
        return 1;
    }

    /*
     * Enumerate over the modules for the current process in order to find
     * kill_process[_d].exe, then take a note of the directory it lives in.
     */
    do {
        if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN))
            continue;

        len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN;
        wcsncpy_s(path, MAX_PATH+1, me.szExePath, len);

        break;

    } while (Module32NextW(hsm, &me));

    CloseHandle(hsm);

    if (path == NULL) {
        printf("failed to discern directory of running process\n");
        return 1;
    }

    /*
     * Take a snapshot of system processes.  Enumerate over the snapshot,
     * looking for python processes.  When we find one, verify it lives
     * in the same directory we live in.  If it does, kill it.  If we're
     * unable to kill it, treat this as a fatal error and return 1.
     *
     * The rationale behind this is that we're called at the start of the
     * build process on the basis that we'll take care of killing any
     * running instances, such that the build won't encounter permission
     * denied errors during linking. If we can't kill one of the processes,
     * we can't provide this assurance, and the build shouldn't start.
     */

    hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hsp == INVALID_HANDLE_VALUE) {
        printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError());
        return 1;
    }

    if (!Process32FirstW(hsp, &pe)) {
        printf("Process32FirstW failed: %d\n", GetLastError());
        CloseHandle(hsp);
        return 1;
    }

    dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE;
    do {

        /*
         * XXX TODO: if we really wanted to be fancy, we could check the
         * modules for all processes (not just the python[_d].exe ones)
         * and see if any of our DLLs are loaded (i.e. python35[_d].dll),
         * as that would also inhibit our ability to rebuild the solution.
         * Not worth loosing sleep over though; for now, a simple check
         * for just the python executable should be sufficient.
         */

        if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN))
            /* This isn't a python process. */
            continue;

        /* It's a python process, so figure out which directory it's in... */
        hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID);
        if (hsm == INVALID_HANDLE_VALUE)
            /*
             * If our module snapshot fails (which will happen if we don't own
             * the process), just ignore it and continue.  (It seems different
             * versions of Windows return different values for GetLastError()
             * in this situation; it's easier to just ignore it and move on vs.
             * stopping the build for what could be a false positive.)
             */
             continue;

        if (!Module32FirstW(hsm, &me)) {
            printf("Module32FirstW[2] failed: %d\n", GetLastError());
            CloseHandle(hsp);
            CloseHandle(hsm);
            return 1;
        }

        do {
            if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN))
                /* Wrong module, we're looking for python[_d].exe... */
                continue;

            if (_wcsnicmp(path, me.szExePath, len))
                /* Process doesn't live in our directory. */
                break;

            /* Python process residing in the right directory, kill it!  */
            hp = OpenProcess(dac, FALSE, pe.th32ProcessID);
            if (!hp) {
                printf("OpenProcess failed: %d\n", GetLastError());
                CloseHandle(hsp);
                CloseHandle(hsm);
                return 1;
            }

            if (!TerminateProcess(hp, 1)) {
                printf("TerminateProcess failed: %d\n", GetLastError());
                CloseHandle(hsp);
                CloseHandle(hsm);
                CloseHandle(hp);
                return 1;
            }

            CloseHandle(hp);
            break;

        } while (Module32NextW(hsm, &me));

        CloseHandle(hsm);

    } while (Process32NextW(hsp, &pe));

    CloseHandle(hsp);

    return 0;
}

/* vi: set ts=8 sw=4 sts=4 expandtab */
