/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * "find_lock.exe", for Windows only.
 *
 * References used:
 *
 * http://drdobbs.com/windows/184411099
 * article by Sven B. Schreiber, November 01, 1999
 *
 * http://www.codeguru.com/Cpp/W-P/system/processesmodules/article.php/c2827/
 * by Zoltan Csizmadia, November 14, 2000
 *
 * http://stackoverflow.com/questions/860656/
 * (same technique, but written in unsafe C#)
 *
 * Starting with Vista, we can also use the Restart Manager API as
 * explained here: (TODO for next version)
 * http://msdn.microsoft.com/en-us/magazine/cc163450.aspx
 */

#ifdef _WIN32

#include "utils.h"
#include <ctype.h>
#include <fcntl.h>
#include <io.h>
#include <process.h>


// NtDll structures from the the Dr Dobbs article, adjusted for our needs:

typedef void *POBJECT;
typedef LONG KPRIORITY;
typedef LARGE_INTEGER QWORD;

typedef struct {
    WORD  Length;
    WORD  MaximumLength;
    PWORD Buffer;
} UNICODE_STRING;

typedef struct {
    DWORD       dIdProcess;
    BYTE        bObjectType;    // OB_TYPE_*
    BYTE        bFlags;         // bits 0..2 HANDLE_FLAG_*
    WORD        wValue;         // multiple of 4
    POBJECT     pObject;
    ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE;

typedef struct {
    DWORD         dCount;
    SYSTEM_HANDLE ash[1];
} SYSTEM_HANDLE_INFORMATION;

typedef struct {
    DWORD PeakVirtualSize;
    DWORD VirtualSize;
    DWORD PageFaultCount;
    DWORD PeakWorkingSetSize;
    DWORD WorkingSetSize;
    DWORD QuotaPeakPagedPoolUsage;
    DWORD QuotaPagedPoolUsage;
    DWORD QuotaPeakNonPagedPoolUsage;
    DWORD QuotaNonPagedPoolUsage;
    DWORD PagefileUsage;
    DWORD PeakPagefileUsage;
} VM_COUNTERS;

typedef struct {
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
} CLIENT_ID;

typedef enum {
    // Ignored. We don't actually use these values.
    Unused
} KWAIT_REASON;

typedef struct {
    QWORD        qKernelTime;       // 100 nsec units
    QWORD        qUserTime;         // 100 nsec units
    QWORD        qCreateTime;       // relative to 01-01-1601
    DWORD        d18;
    PVOID        pStartAddress;
    CLIENT_ID    Cid;               // process/thread ids
    DWORD        dPriority;
    DWORD        dBasePriority;
    DWORD        dContextSwitches;
    DWORD        dThreadState;      // 2=running, 5=waiting
    KWAIT_REASON WaitReason;
    DWORD        dReserved01;
} SYSTEM_THREAD;

typedef struct {
    DWORD          dNext;           // relative offset
    DWORD          dThreadCount;
    DWORD          dReserved01;
    DWORD          dReserved02;
    DWORD          dReserved03;
    DWORD          dReserved04;
    DWORD          dReserved05;
    DWORD          dReserved06;
    QWORD          qCreateTime;     // relative to 01-01-1601
    QWORD          qUserTime;       // 100 nsec units
    QWORD          qKernelTime;     // 100 nsec units
    UNICODE_STRING usName;
    KPRIORITY      BasePriority;
    DWORD          dUniqueProcessId;
    DWORD          dInheritedFromUniqueProcessId;
    DWORD          dHandleCount;
    DWORD          dReserved07;
    DWORD          dReserved08;
    VM_COUNTERS    VmCounters;
    DWORD          dCommitCharge;   // bytes
    SYSTEM_THREAD  ast[1];
} SYSTEM_PROCESS_INFORMATION;

// The sic opcode for NtQuerySystemInformation
typedef enum {
    SystemProcessInformation = 5,
    SystemHandleInformation = 16,
} SYSTEMINFOCLASS;


#define STATUS_SUCCESS               0x00000000
#define STATUS_UNSUCCESSFUL          0xC0000001
#define STATUS_NOT_IMPLEMENTED       0xC0000002
#define STATUS_INVALID_INFO_CLASS    0xC0000003
#define STATUS_INFO_LENGTH_MISMATCH  0xC0000004
#define STATUS_INVALID_PARAMETER     0xC000000D

typedef DWORD (WINAPI *NtQuerySystemInformationFuncPtr)(
                                      DWORD sic, VOID* pData, DWORD sSize, ULONG* pdSize);
typedef DWORD (WINAPI *NtQueryInformationFileFuncPtr)(HANDLE, PVOID, PVOID, DWORD, DWORD);
typedef DWORD (WINAPI *NtQueryObjectFuncPtr)(HANDLE, DWORD, VOID*, DWORD, VOID*);

static NtQuerySystemInformationFuncPtr sNtQuerySystemInformationFunc;
static NtQueryInformationFileFuncPtr   sNtQueryInformationFileFunc;
static NtQueryObjectFuncPtr            sNtQueryObjectFunc;

//------------

// Get the NT DLL functions we need to use.
static bool init() {

    sNtQuerySystemInformationFunc =
        (NtQuerySystemInformationFuncPtr) GetProcAddress(
            GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation");

    sNtQueryInformationFileFunc =
        (NtQueryInformationFileFuncPtr) GetProcAddress(
            GetModuleHandleA("ntdll.dll"), "NtQueryInformationFile");

    sNtQueryObjectFunc =
        (NtQueryObjectFuncPtr) GetProcAddress(
            GetModuleHandleA("ntdll.dll"), "NtQueryObject");

    return sNtQuerySystemInformationFunc != NULL &&
           sNtQueryInformationFileFunc   != NULL &&
           sNtQueryObjectFunc            != NULL;
}

static void terminate() {
    sNtQuerySystemInformationFunc = NULL;
    sNtQueryInformationFileFunc = NULL;
    sNtQueryObjectFunc = NULL;
}

static bool adjustPrivileges() {
    char *error = NULL;
    HANDLE tokenH;

    // Open a process token that lets us adjust privileges
    BOOL ok = OpenProcessToken(GetCurrentProcess(),   // ProcessHandle
                               TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, // DesiredAccess
                               &tokenH);              // TokenHandle
    if (!ok) {
        error = "OpenProcessToken failed: ";
        goto bail_out;
    }

    // Lookup the privilege by name and get its local LUID token.
    // What we request:
    // SE_DEBUG_NAME, aka "SeDebugPrivilege"
    // MSDN: Required to debug and adjust the memory of a process owned by another account.
    //       User Right: Debug programs.
    TOKEN_PRIVILEGES priv;
    priv.PrivilegeCount = 1;
    priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    ok = LookupPrivilegeValueA(NULL,                        // lpSystemName
                               SE_DEBUG_NAME,               // lpName
                               &(priv.Privileges[0].Luid)); // lpLuid
    if (!ok) {
        error = "LookupPrivilegeValue failed: ";
        goto bail_out;
    }

    ok = AdjustTokenPrivileges(tokenH,  // TokenHandle
                               FALSE,   // DisableAllPrivileges
                               &priv,   // NewState
                               0,       // BufferLength
                               NULL,    // PreviousState
                               0);      // ReturnLength
    if (!ok) {
        error = "AdjustTokenPrivileges failed: ";
        goto bail_out;
    }

bail_out:
    if (error != NULL && gIsDebug) {
        CString err;
        err.setLastWin32Error(error);
        fprintf(stderr, "%s", err.cstr());
    }

    if (tokenH != NULL) {
        CloseHandle(tokenH);
    }

    return !!ok;
}

static bool getHandleType(HANDLE h, CString *type) {
    bool result = false;
    ULONG size = 0;
    // Get the size of the type string
    int status = sNtQueryObjectFunc(h, 2, NULL, 0, &size);
    if (status == STATUS_INFO_LENGTH_MISMATCH && size > 0) {
        // Get the type string itself
        char *buf = new char[size];
        status = sNtQueryObjectFunc(h, 2, buf, size, NULL);
        if (status == 0 && size > 96) {
            // The type string we want is a wide unicode (UTF16)
            // zero-terminated string located at offset 96 in the
            // buffer. In our case we want the string to be
            // "Directory" or "File" so we know the max useful length
            // is 9.
            // Since we can only deal with ansi strings in this program,
            // we'll make a crude copy of every other byte and just check
            // that the other bytes are zero.
            const char *c = buf + 96;
            const char *e = buf + 96 + size;
            // we'll write at the beginning of our buffer
            char *dest = buf;
            char *dend = dest + 9;
            for (; c < e && dest < dend && c[0] != '\0' && c[1] == '\0'; c += 2, dest++) {
                *dest = *c;
            }
            *(dest++) = '\0';
            type->set(buf, dest - buf);
            result = true;
        }

        free(buf);
    }
    return result;
}

// These is the wide unicode representations of the type we want to find.
static const char kFileW[] = "File";

static char isFileHandleType(HANDLE handle) {
    char type = 0;
    ULONG size = 0;
    // Get the size of the type string
    int status = sNtQueryObjectFunc(handle, 2, NULL, 0, &size);
    if (status == STATUS_INFO_LENGTH_MISMATCH && size > 0) {
        // Get the type string itself
        char *buf = new char[size];
        status = sNtQueryObjectFunc(handle, 2, buf, size, NULL);
        if (status == 0 && size > 96) {
            // The type string we want is a wide unicode (UTF16-LE)
            // zero-terminated string located at offset 96 in the
            // buffer. In our case we want the string to be "File".
            //
            // Since we're reading wide unicode, we want each character
            // to be the one from our string followed by a zero byte.
            // e.g. c should point to F \0 i \0 l \0 e \0 \0 \0.
            const char *c = buf + 96;
            type = c[0];

            int len = sizeof(kFileW);
            const char *d = kFileW;

            for (; type != 0 && len > 0; c+=2, d++, len--) {
                if (c[0] != *d || c[1] != 0) {
                    type = 0;
                    break;
                }
            }
        }

        free(buf);
    }
    return type;
}

typedef struct {
    HANDLE handle;
    CString *outStr;
    bool result;
} SFileNameInfo;

static unsigned __stdcall FileNameThreadFunc(void *param) {
    SFileNameInfo *info = (SFileNameInfo *)param;
    if (info == NULL) {
        return 1;
    }

    char buf[MAX_PATH*2 + 4];
    DWORD iob[2] = { 0, 0 };

    DWORD status = sNtQueryInformationFileFunc(info->handle, iob, buf, sizeof(buf), 9);
    if (status == STATUS_SUCCESS) {
        // The result is a buffer with:
        // - DWORD (4 bytes) for the *byte* length (so twice the character length)
        // - Actual string in Unicode
        // Not sure of the actual type, but it does look like a UNICODE_STRING struct.

        DWORD len = ((DWORD *)buf)[0];
        if (len <= MAX_PATH * 2) {
            // We can't handle wide Unicode. What we do is convert it into
            // straight ansi by just retaining the first of each couple bytes.
            // Bytes that cannot be mapped (e.g. 2nd byte is != 0) will be
            // simply converted to 0xFF.

            unsigned char *dest = (unsigned char *)buf + 4;
            unsigned char *src  = (unsigned char *)buf + 4;
            for (DWORD i = 0; i < len; dest++, src += 2, i += 2) {
                if (src[1] == 0) {
                    *dest = *src;
                } else {
                    *dest = 0xFF;
                }
            }
            *dest = '\0';
            info->outStr->set(buf + 4, len);
            info->result = true;
            return 0;
        }
    }
    return 1;
}

static bool getFileName(HANDLE handle, CString *outStr) {
    SFileNameInfo info;
    info.handle = handle;
    info.outStr = outStr;
    info.result = false;

    // sNtQueryInformationFileFunc might hang on some handles.
    // A trick is to do it in a thread and if it takes too loog then
    // just shutdown the thread, since it's deadlocked anyway.
    unsigned threadId;
    HANDLE th = (HANDLE)_beginthreadex(NULL,                    // security
                                       0,                       // stack_size
                                       &FileNameThreadFunc,     // address
                                       &info,                   // arglist
                                       0,                       // initflag
                                       &threadId);              // thrdaddr

    if (th == NULL) {
        // Failed to create thread. Shouldn't really happen.
        outStr->set("<failed to create thread>");
        return false;
    }

    bool result = false;

    // Wait for thread or kill it if it takes too long.
    if (WaitForSingleObject(th /*handle*/, 200 /*ms*/) == WAIT_TIMEOUT) {
        TerminateThread(th /*handle*/, 0 /*retCode*/);
        outStr->set("<timeout>");
    } else {
        result = info.result;
    }

    CloseHandle(th);
    return result;
}

// Find the name of the process (e.g. "java.exe") given its id.
// processesPtr must be the list returned by getAllProcesses().
// Special handling for javaw.exe: this isn't quite useful so
// we also try to find and append the parent process name.
static bool getProcessName(SYSTEM_PROCESS_INFORMATION *processesPtr,
                           DWORD remoteProcessId,
                           CString *outStr) {
    SYSTEM_PROCESS_INFORMATION *ptr = processesPtr;
    while (ptr != NULL) {
        if (ptr->dUniqueProcessId == remoteProcessId) {
            // This is the process we want.

            UNICODE_STRING *uniStr = &(ptr->usName);
            WORD len = uniStr->Length;

            char buf[MAX_PATH];
            if (len <= MAX_PATH * 2) {
                // We can't handle wide Unicode. What we do is convert it into
                // straight ansi by just retaining the first of each couple bytes.
                // Bytes that cannot be mapped (e.g. 2nd byte is != 0) will be
                // simply converted to 0xFF.

                unsigned char *dest = (unsigned char *)buf;
                unsigned char *src  = (unsigned char *)uniStr->Buffer;
                for (WORD i = 0; i < len; dest++, src += 2, i += 2) {
                    if (src[1] == 0) {
                        *dest = *src;
                    } else {
                        *dest = 0xFF;
                    }
                }
                *dest = '\0';
                outStr->set(buf, len);

                if (strcmp(buf, "javaw.exe") == 0) {
                    // Heuristic: eclipse often shows up as javaw.exe
                    // but what is useful is to report eclipse to the user
                    // instead.
                    // So in this case, look at the parent and report it too.
                    DWORD parentId = ptr->dInheritedFromUniqueProcessId;
                    if (parentId > 0) {
                        CString name2;
                        bool ok2 = getProcessName(processesPtr,
                                                  parentId,
                                                  &name2);
                        if (ok2) {
                            outStr->add(" (");
                            outStr->add(name2.cstr());
                            outStr->add(")");
                        }
                    }
                }

                return true;
            }
        }

        // Look at the next process, if any.
        if (ptr->dNext == NULL) {
            break;
        } else {
            ptr = (SYSTEM_PROCESS_INFORMATION *)((char *)ptr + ptr->dNext);
        }
    }

    outStr->setf("<process id %08x name not found>", remoteProcessId);
    return false;
}

// Query system for all processes information.
// Returns an error string in case of error.
// Returns the virtual_alloc-allocated buffer on success or NULL on error.
// It's up to the caller to do a VirtualFree on the returned buffer.
static SYSTEM_PROCESS_INFORMATION *queryAllProcess(const char **error) {
    // Allocate a buffer for the process information. We don't know the
    // exact size. A normal system might typically have between 100-200 processes.
    // We'll resize the buffer if not big enough.
    DWORD infoSize = 4096;
    SYSTEM_PROCESS_INFORMATION *infoPtr =
        (SYSTEM_PROCESS_INFORMATION *) VirtualAlloc(NULL, infoSize, MEM_COMMIT, PAGE_READWRITE);

    if (infoPtr != NULL) {
        // Query the actual size needed (or the data if it fits in the buffer)
        DWORD needed = 0;
        if (sNtQuerySystemInformationFunc(
                SystemProcessInformation, infoPtr, infoSize, &needed) != 0) {
            if (needed == 0) {
                // Shouldn't happen.
                *error = "No processes found";
                goto bail_out;
            }

            // Realloc
            VirtualFree(infoPtr, 0, MEM_RELEASE);
            infoSize += needed;
            infoPtr = (SYSTEM_PROCESS_INFORMATION *) VirtualAlloc(
                            NULL, infoSize, MEM_COMMIT, PAGE_READWRITE);

            // Query all the processes objects again
            if (sNtQuerySystemInformationFunc(
                    SystemProcessInformation, infoPtr, infoSize, NULL) != 0) {
                *error = "Failed to query system processes";
                goto bail_out;
            }
        }
    }

    if (infoPtr == NULL) {
        *error = "Failed to allocate system processes info buffer";
        goto bail_out;
    }

bail_out:
    if (*error != NULL) {
        VirtualFree(infoPtr, 0, MEM_RELEASE);
        infoPtr = NULL;
    }
    return infoPtr;
}

// Query system for all handle information.
// Returns an error string in case of error.
// Returns the virtual_alloc-allocated buffer on success or NULL on error.
// It's up to the caller to do a VirtualFree on the returned buffer.
static SYSTEM_HANDLE_INFORMATION *queryAllHandles(const char **error) {
    // Allocate a buffer. It won't be large enough to get the handles
    // (e.g. there might be 10k or 40k handles around). We'll resize
    // it once we know the actual size.
    DWORD infoSize = 4096;
    SYSTEM_HANDLE_INFORMATION *infoPtr =
        (SYSTEM_HANDLE_INFORMATION *) VirtualAlloc(NULL, infoSize, MEM_COMMIT, PAGE_READWRITE);

    if (infoPtr != NULL) {
        // Query the actual size needed
        DWORD needed = 0;
        if (sNtQuerySystemInformationFunc(
                SystemHandleInformation, infoPtr, infoSize, &needed) != 0) {
            if (needed == 0) {
                // Shouldn't happen.
                *error = "No handles found";
                goto bail_out;
            }

            // Realloc
            VirtualFree(infoPtr, 0, MEM_RELEASE);
            infoSize += needed;
            infoPtr = (SYSTEM_HANDLE_INFORMATION *) VirtualAlloc(
                            NULL, infoSize, MEM_COMMIT, PAGE_READWRITE);
        }
    }

    if (infoPtr == NULL) {
        *error = "Failed to allocate system handle info buffer";
        goto bail_out;
    }

    // Query all the handle objects
    if (sNtQuerySystemInformationFunc(SystemHandleInformation, infoPtr, infoSize, NULL) != 0) {
        *error = "Failed to query system handles";
        goto bail_out;
    }

bail_out:
    if (*error != NULL) {
        VirtualFree(infoPtr, 0, MEM_RELEASE);
        infoPtr = NULL;
    }
    return infoPtr;
}

bool findLock(CPath &path, CString *outModule) {
    bool result = false;
    const char *error = NULL;

    SYSTEM_PROCESS_INFORMATION *processesPtr = NULL;
    SYSTEM_HANDLE_INFORMATION  *handlesPtr   = NULL;

    const HANDLE currProcessH = GetCurrentProcess();
    const DWORD currProcessId = GetCurrentProcessId();
    HANDLE remoteProcessH = NULL;
    DWORD remoteProcessId = 0;
    DWORD matchProcessId = 0;

    int numHandleFound = 0;
    int numHandleChecked = 0;
    int numHandleDirs = 0;
    int numHandleFiles = 0;
    int numProcessMatch = 0;

    BYTE ob_type_file = 0;

    // Get the path to search, without the drive letter.
    const char *searchPath = path.cstr();
    if (isalpha(searchPath[0]) && searchPath[1] == ':') {
        searchPath += 2;
    }
    size_t searchPathLen = strlen(searchPath);

    if (gIsDebug) fprintf(stderr, "Search path: '%s'\n", searchPath);

    if (!init()) {
        error = "Failed to bind to ntdll.dll";
        goto bail_out;
    }

    if (!adjustPrivileges()) {
        // We can still continue even if the privilege escalation failed.
        // The apparent effect is that we'll fail to query the name of
        // some processes, yet it will work for some of them.
        if (gIsDebug) fprintf(stderr, "Warning: adusting privileges failed. Continuing anyway.\n");
    } else {
        if (gIsDebug) fprintf(stderr, "Privileges adjusted.\n"); // DEBUG remove lter
    }

    processesPtr = queryAllProcess(&error);
    if (processesPtr == NULL) goto bail_out;

    handlesPtr = queryAllHandles(&error);
    if (handlesPtr == NULL) goto bail_out;

    numHandleFound = handlesPtr->dCount;

    // Check all the handles
    for (int n = handlesPtr->dCount, i = 0; i < n; i++) {
        SYSTEM_HANDLE sysh = handlesPtr->ash[i];

        if (ob_type_file != 0 && sysh.bObjectType != ob_type_file) {
            continue;
        }

        HANDLE handle = (HANDLE) sysh.wValue;
        DWORD remoteId = sysh.dIdProcess;
        HANDLE remoteH = NULL;

        if (remoteId == matchProcessId) {
            // We already matched that process, we can skip its other entries.
            continue;
        }

        if (remoteId == currProcessId) {
            // We don't match ourselves
            continue;
        }

        // Open a remote process.
        // Most entries of a given process seem to be consecutive, so we
        // only open the remote process handle if it's a different id.
        if (remoteProcessH == NULL && remoteId == remoteProcessId) {
            // We already tried to open this process and it failed.
            // It's not going to be any better the next time so skip it.
            continue;
        }
        if (remoteProcessH == NULL || remoteId != remoteProcessId) {
            if (remoteProcessH != NULL) {
                CloseHandle(remoteProcessH);
            }

            remoteProcessId = remoteId;
            remoteProcessH = OpenProcess(PROCESS_DUP_HANDLE,
                                         FALSE /*inheritHandle*/,
                                         remoteProcessId);
            if (remoteProcessH == NULL) {
                continue;
            }
        }

        if (remoteProcessH != NULL) {
            // Duplicate the remote handle
            if (DuplicateHandle(remoteProcessH,     // hSourceProcessHandle
                                handle,             // hSourceHandle
                                currProcessH,       // hTargetProcessHandle
                                &remoteH,           // lpTargetHandle
                                0,                  // dwDesiredAccess (ignored by same access)
                                FALSE,              // bInheritHandle
                                DUPLICATE_SAME_ACCESS) == 0) {
                continue;
            }
        }

        numHandleChecked++;

        char type = isFileHandleType(remoteH);

        if (type != 0) {
            if (type == 'D') numHandleDirs++;
            else if (type == 'F') numHandleFiles++;

            // TODO simplify by not keeping directory handles
            if (ob_type_file == 0 && type == 'F') {
                // We found the first file handle. Remember it's system_handle object type
                // and then use it to filter the following system_handle.
                // For some reason OB_TYPE_FILE should be 0x1A but empirically I find it
                // to be 0x1C, so we just make this test more dynamic.
                ob_type_file = sysh.bObjectType;
            }

            // Try to get a filename out of that file or directory handle.
            CString name("<unknown>");
            bool ok = getFileName(remoteH, &name);

            if (gIsDebug) {
                fprintf(stderr, "P:%08x | t:%02x | f:%02x | v:%08x | %c | %s %s\n",
                    sysh.dIdProcess, sysh.bObjectType, sysh.bFlags, sysh.wValue,
                    type,
                    ok ? "OK" : "FAIL",
                    name.cstr()
                    );
            }

            if (ok) {
                // We got a file path. Let's check if it matches our target path.
                if (_strnicmp(searchPath, name.cstr(), searchPathLen) == 0) {
                    // Remember this process id so that we can ignore all its following entries.
                    matchProcessId = remoteId;

                    // Find out its process name
                    CString procName("<unknown>");
                    ok = getProcessName(processesPtr, remoteProcessId, &procName);
                    if (ok) {
                        numProcessMatch++;

                        if (!outModule->isEmpty()) {
                            outModule->add(";");
                        }
                        outModule->add(procName.cstr());
                        result = true;
                    }

                    if (gIsDebug) {
                        fprintf(stderr, "==> MATCH FOUND: %s  %s\n",
                            ok ? "OK" : "FAIL",
                            procName.cstr()
                            );
                    }
                }
            }

        }

        if (remoteH != NULL) {
            CloseHandle(remoteH);
            remoteH = NULL;
        }
    }

bail_out:

    if (gIsDebug) {
        fprintf(stderr, "Processes matched: %d\n", numProcessMatch);
        fprintf(stderr, "Handles: %d found, %d checked, %d dirs, %d files\n",
               numHandleFound,
               numHandleChecked,
               numHandleDirs,
               numHandleFiles);
    }

    if (error != NULL) {
        CString msg;
        msg.setLastWin32Error(NULL);
        if (gIsDebug) fprintf(stderr, "[ERROR] %s: %s", error, msg.cstr());
    }

    if (remoteProcessH != NULL) {
        CloseHandle(remoteProcessH);
    }

    if (currProcessH != NULL) {
        CloseHandle(currProcessH);
    }

    if (handlesPtr != NULL) {
        VirtualFree(handlesPtr, 0, MEM_RELEASE);
        handlesPtr = NULL;
    }

    terminate();

    return result;
}

#endif /* _WIN32 */
