/*
 * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


#include "jni.h"
#include "jvm.h"
#include "jni_util.h"
#include "java_lang_ProcessHandleImpl.h"
#include "java_lang_ProcessHandleImpl_Info.h"

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

static void getStatInfo(JNIEnv *env, HANDLE handle, jobject jinfo);
static void getCmdlineInfo(JNIEnv *env, HANDLE handle, jobject jinfo);
static void procToUser(JNIEnv *env, HANDLE handle, jobject jinfo);

/**************************************************************
 * Implementation of ProcessHandleImpl_Info native methods.
 */

/* Field id for jString 'command' in java.lang.ProcessHandle.Info */
static jfieldID ProcessHandleImpl_Info_commandID;

/* Field id for jString 'commandLine' in java.lang.ProcessHandleImpl.Info */
static jfieldID ProcessHandleImpl_Info_commandLineID;

/* Field id for jString[] 'arguments' in java.lang.ProcessHandle.Info */
static jfieldID ProcessHandleImpl_Info_argumentsID;

/* Field id for jlong 'totalTime' in java.lang.ProcessHandle.Info */
static jfieldID ProcessHandleImpl_Info_totalTimeID;

/* Field id for jlong 'startTime' in java.lang.ProcessHandle.Info */
static jfieldID ProcessHandleImpl_Info_startTimeID;

/* Field id for jString 'accountName' in java.lang.ProcessHandleImpl.UserPrincipal */
static jfieldID ProcessHandleImpl_Info_userID;

/**************************************************************
 * Static method to initialize field IDs.
 *
 * Class:     java_lang_ProcessHandleImpl_Info
 * Method:    initIDs
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_java_lang_ProcessHandleImpl_00024Info_initIDs(JNIEnv *env, jclass clazz) {

    CHECK_NULL(ProcessHandleImpl_Info_commandID = (*env)->GetFieldID(env,
        clazz, "command", "Ljava/lang/String;"));
    CHECK_NULL(ProcessHandleImpl_Info_commandLineID = (*env)->GetFieldID(env,
        clazz, "commandLine", "Ljava/lang/String;"));
    CHECK_NULL(ProcessHandleImpl_Info_argumentsID = (*env)->GetFieldID(env,
        clazz, "arguments", "[Ljava/lang/String;"));
    CHECK_NULL(ProcessHandleImpl_Info_totalTimeID = (*env)->GetFieldID(env,
        clazz, "totalTime", "J"));
    CHECK_NULL(ProcessHandleImpl_Info_startTimeID = (*env)->GetFieldID(env,
        clazz, "startTime", "J"));
    CHECK_NULL(ProcessHandleImpl_Info_userID = (*env)->GetFieldID(env,
        clazz, "user", "Ljava/lang/String;"));
}
/**************************************************************
 * Static method to initialize native.
 *
 * Class:     java_lang_ProcessHandleImpl
 * Method:    initNative
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_java_lang_ProcessHandleImpl_initNative(JNIEnv *env, jclass clazz) {
}

/*
 * Block until a child process exits and return its exit code.
 */
JNIEXPORT jint JNICALL
Java_java_lang_ProcessHandleImpl_waitForProcessExit0(JNIEnv* env,
                                                     jclass junk,
                                                     jlong jpid,
                                                     jboolean reapStatus) {
    DWORD pid = (DWORD)jpid;
    DWORD exitValue = -1;
    HANDLE handle = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION,
                                FALSE, pid);
    if (handle == NULL) {
        return exitValue;          // No process with that pid is alive
    }
    if (!GetExitCodeProcess(handle, &exitValue)) {
        JNU_ThrowByNameWithLastError(env,
            "java/lang/RuntimeException", "GetExitCodeProcess");
    } else if (exitValue == STILL_ACTIVE) {
        if (WaitForSingleObject(handle, INFINITE) /* Wait forever */
            == WAIT_FAILED) {
            JNU_ThrowByNameWithLastError(env,
                "java/lang/RuntimeException", "WaitForSingleObjects");
        } else if (!GetExitCodeProcess(handle, &exitValue)) {
            JNU_ThrowByNameWithLastError(env,
                "java/lang/RuntimeException", "GetExitCodeProcess");
        }
    }
    CloseHandle(handle);         // Ignore return code
    return exitValue;
}

/*
 * Returns the pid of the caller.
 *
 * Class:     java_lang_ProcessHandleImpl
 * Method:    getCurrentPid0
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL
Java_java_lang_ProcessHandleImpl_getCurrentPid0(JNIEnv *env, jclass clazz) {
    DWORD  pid = GetCurrentProcessId();
    return (jlong)pid;
}

/*
 * Returns the parent pid of the requested pid.
 *
 * Class:     java_lang_ProcessHandleImpl
 * Method:    parent0
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL
Java_java_lang_ProcessHandleImpl_parent0(JNIEnv *env,
                                         jclass clazz,
                                         jlong jpid,
                                         jlong startTime) {
    DWORD ppid = 0;
    DWORD wpid = (DWORD)jpid;
    PROCESSENTRY32 pe32;
    HANDLE hProcessSnap;
    jlong start;

    start = Java_java_lang_ProcessHandleImpl_isAlive0(env, clazz, jpid);
    if (start != startTime && start != 0 && startTime != 0) {
        return -1;
    }

    // Take a snapshot of all processes in the system.
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE) {
        JNU_ThrowByName(env,
            "java/lang/RuntimeException", "snapshot not available");
        return -1;
    }

    // Retrieve information about the first process,
    pe32.dwSize = sizeof (PROCESSENTRY32);
    if (Process32First(hProcessSnap, &pe32)) {
        // Now walk the snapshot of processes, and
        do {
            if (wpid == pe32.th32ProcessID) {
                // The parent PID may be stale if that process has exited
                // and may have been reused.
                // A valid parent's start time is the same or before the child's
                jlong ppStartTime = Java_java_lang_ProcessHandleImpl_isAlive0(env,
                        clazz, pe32.th32ParentProcessID);
                if (ppStartTime > 0 && ppStartTime <= startTime) {
                    ppid = pe32.th32ParentProcessID;
                }
                break;
            }
        } while (Process32Next(hProcessSnap, &pe32));
    } else {
        JNU_ThrowByName(env,
            "java/lang/RuntimeException", "snapshot not available");
        ppid = (DWORD)-1;
    }
    CloseHandle(hProcessSnap); // Ignore return code
    return (jlong)ppid;
}

/*
 * Returns the children of the requested pid and optionally each parent.
 *
 * Class:     java_lang_ProcessHandleImpl
 * Method:    getChildPids
 * Signature: (J[J[J)I
 */
JNIEXPORT jint JNICALL
Java_java_lang_ProcessHandleImpl_getProcessPids0(JNIEnv *env,
                                                 jclass clazz,
                                                 jlong jpid,
                                                 jlongArray jarray,
                                                 jlongArray jparentArray,
                                                 jlongArray jstimesArray) {
    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    DWORD ppid = (DWORD)jpid;
    jlong* pids = NULL;
    jlong* ppids = NULL;
    jlong* stimes = NULL;
    jsize parentArraySize = 0;
    jsize arraySize = 0;
    jsize stimesSize = 0;
    jsize count = 0;

    arraySize = (*env)->GetArrayLength(env, jarray);
    JNU_CHECK_EXCEPTION_RETURN(env, -1);
    if (jparentArray != NULL) {
        parentArraySize = (*env)->GetArrayLength(env, jparentArray);
        JNU_CHECK_EXCEPTION_RETURN(env, -1);

        if (arraySize != parentArraySize) {
            JNU_ThrowIllegalArgumentException(env, "array sizes not equal");
            return 0;
        }
    }
    if (jstimesArray != NULL) {
        stimesSize = (*env)->GetArrayLength(env, jstimesArray);
        JNU_CHECK_EXCEPTION_RETURN(env, -1);

        if (arraySize != stimesSize) {
            JNU_ThrowIllegalArgumentException(env, "array sizes not equal");
            return 0;
        }
    }

    // Take a snapshot of all processes in the system.
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE) {
        JNU_ThrowByName(env,
            "java/lang/RuntimeException", "snapshot not available");
        return 0;
    }

    // Retrieve information about the first process,
    pe32.dwSize = sizeof (PROCESSENTRY32);
    if (Process32First(hProcessSnap, &pe32)) {
        do { // Block to break out of on Exception
            pids = (*env)->GetLongArrayElements(env, jarray, NULL);
            if (pids == NULL) {
                break;
            }
            if (jparentArray != NULL) {
                ppids = (*env)->GetLongArrayElements(env, jparentArray, NULL);
                if (ppids == NULL) {
                    break;
                }
            }
            if (jstimesArray != NULL) {
                stimes = (*env)->GetLongArrayElements(env, jstimesArray, NULL);
                if (stimes == NULL) {
                    break;
                }
            }
            // Now walk the snapshot of processes, and
            // save information about each process in turn
            do {
                if (ppid == 0 ||
                    (pe32.th32ParentProcessID > 0
                    && (pe32.th32ParentProcessID == ppid))) {
                    if (count < arraySize) {
                        // Only store if it fits
                        pids[count] = (jlong) pe32.th32ProcessID;
                        if (ppids != NULL) {
                            // Store the parentPid
                            ppids[count] = (jlong) pe32.th32ParentProcessID;
                        }
                        if (stimes != NULL) {
                            // Store the process start time
                            stimes[count] =
                                    Java_java_lang_ProcessHandleImpl_isAlive0(env,
                                            clazz, (jlong) pe32.th32ProcessID);
                        }
                    }
                    count++;    // Count to tabulate size needed
                }
            } while (Process32Next(hProcessSnap, &pe32));
        } while (0);

        if (pids != NULL) {
            (*env)->ReleaseLongArrayElements(env, jarray, pids, 0);
        }
        if (ppids != NULL) {
            (*env)->ReleaseLongArrayElements(env, jparentArray, ppids, 0);
        }
        if (stimes != NULL) {
            (*env)->ReleaseLongArrayElements(env, jstimesArray, stimes, 0);
        }
    } else {
        JNU_ThrowByName(env,
            "java/lang/RuntimeException", "snapshot not available");
        count = 0;
    }
    CloseHandle(hProcessSnap);
    // If more pids than array had size for;  count will be greater than array size
    return (jint)count;
}

/**
 * Assemble a 64 bit value from two 32 bit values.
 */
static jlong jlong_from(jint high, jint low) {
    jlong result = 0;
    result = ((jlong)high << 32) | ((0x000000000ffffffff) & (jlong)low);
    return result;
}

/*
 * Get the start time in ms from 1970 from the handle.
 */
static jlong getStartTime(HANDLE handle) {
    FILETIME CreationTime, ExitTime, KernelTime, UserTime;
    if (GetProcessTimes(handle, &CreationTime, &ExitTime, &KernelTime, &UserTime)) {
        jlong start = jlong_from(CreationTime.dwHighDateTime,
                                 CreationTime.dwLowDateTime) / 10000;
        start -= 11644473600000L; // Rebase Epoch from 1601 to 1970
        return start;
    } else {
        return 0;
    }
}

/*
 * Destroy the process.
 *
 * Class:     java_lang_ProcessHandleImpl
 * Method:    destroy0
 * Signature: (Z)V
 */
JNIEXPORT jboolean JNICALL
Java_java_lang_ProcessHandleImpl_destroy0(JNIEnv *env,
                                          jclass clazz,
                                          jlong jpid,
                                          jlong startTime,
                                          jboolean force) {
    DWORD pid = (DWORD)jpid;
    jboolean ret = JNI_FALSE;
    HANDLE handle = OpenProcess(PROCESS_TERMINATE | THREAD_QUERY_INFORMATION
                                | PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
    if (handle != NULL) {
        jlong start = getStartTime(handle);
        if (start == startTime || startTime == 0) {
            ret = TerminateProcess(handle, 1) ? JNI_TRUE : JNI_FALSE;
        }
        CloseHandle(handle);         // Ignore return code
    }
    return ret;
}

 /*
 * Check if a process is alive.
 * Return the start time (ms since 1970) if it is available.
 * If the start time is not available return 0.
 * If the pid is invalid, return -1.
 *
 * Class:     java_lang_ProcessHandleImpl
 * Method:    isAlive0
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL
Java_java_lang_ProcessHandleImpl_isAlive0(JNIEnv *env, jclass clazz, jlong jpid) {
    DWORD pid = (DWORD)jpid;

    jlong ret = -1;
    HANDLE handle =
        OpenProcess(THREAD_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION,
                    FALSE, pid);
    if (handle != NULL) {
        DWORD dwExitStatus;

        GetExitCodeProcess(handle, &dwExitStatus);
        if (dwExitStatus == STILL_ACTIVE) {
            ret = getStartTime(handle);
        } else {
            ret = -1;
        }
        CloseHandle(handle); // Ignore return code
   }
   return ret;
}

/*
 * Fill in the Info object from the OS information about the process.
 *
 * Class:     java_lang_ProcessHandleImpl
 * Method:    info0
 * Signature: (J)V
 */
JNIEXPORT void JNICALL
Java_java_lang_ProcessHandleImpl_00024Info_info0(JNIEnv *env,
                                                 jobject jinfo,
                                                 jlong jpid) {
    DWORD pid = (DWORD)jpid;
    HANDLE handle =
        OpenProcess(THREAD_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION,
                    FALSE, pid);
    if (handle == NULL) {
        return;
    }
    getStatInfo(env, handle, jinfo);
    getCmdlineInfo(env, handle, jinfo);
    procToUser(env, handle, jinfo);

    CloseHandle(handle);                // Ignore return code
}

/**
 * Read /proc/<pid>/stat and fill in the fields of the Info object.
 * The executable name, plus the user, system, and start times are gathered.
 */
static void getStatInfo(JNIEnv *env, HANDLE handle, jobject jinfo) {
    FILETIME CreationTime;
    FILETIME ExitTime;
    FILETIME KernelTime;
    FILETIME UserTime;
    jlong userTime;             // nanoseconds
    jlong totalTime;            // nanoseconds
    jlong startTime;            // nanoseconds
    UserTime.dwHighDateTime = 0;
    UserTime.dwLowDateTime = 0;
    KernelTime.dwHighDateTime = 0;
    KernelTime.dwLowDateTime = 0;
    CreationTime.dwHighDateTime = 0;
    CreationTime.dwLowDateTime = 0;

    if (GetProcessTimes(handle, &CreationTime, &ExitTime, &KernelTime, &UserTime)) {
        userTime = jlong_from(UserTime.dwHighDateTime, UserTime.dwLowDateTime);
        totalTime = jlong_from( KernelTime.dwHighDateTime, KernelTime.dwLowDateTime);
        totalTime = (totalTime + userTime) * 100;  // convert sum to nano-seconds

        startTime = jlong_from(CreationTime.dwHighDateTime,
                               CreationTime.dwLowDateTime) / 10000;
        startTime -= 11644473600000L; // Rebase Epoch from 1601 to 1970

        (*env)->SetLongField(env, jinfo,
                             ProcessHandleImpl_Info_totalTimeID, totalTime);
        JNU_CHECK_EXCEPTION(env);
        (*env)->SetLongField(env, jinfo,
                             ProcessHandleImpl_Info_startTimeID, startTime);
        JNU_CHECK_EXCEPTION(env);
    }
}

static void getCmdlineInfo(JNIEnv *env, HANDLE handle, jobject jinfo) {
    WCHAR exeName[1024];
    WCHAR *longPath;
    DWORD bufsize = sizeof(exeName)/sizeof(WCHAR);
    jstring commandObj = NULL;

    if (QueryFullProcessImageNameW(handle, 0,  exeName, &bufsize)) {
        commandObj = (*env)->NewString(env, (const jchar *)exeName,
                                       (jsize)wcslen(exeName));
    } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
        bufsize = 32768;
        longPath = (WCHAR*)malloc(bufsize * sizeof(WCHAR));
        if (longPath != NULL) {
            if (QueryFullProcessImageNameW(handle, 0, longPath, &bufsize)) {
                commandObj = (*env)->NewString(env, (const jchar *)longPath,
                                               (jsize)wcslen(longPath));
            }
            free(longPath);
        }
    }
    CHECK_NULL(commandObj);
    (*env)->SetObjectField(env, jinfo,
                           ProcessHandleImpl_Info_commandID, commandObj);
}

static void procToUser(JNIEnv *env, HANDLE handle, jobject jinfo) {
#define TOKEN_LEN 256
    DWORD token_len = TOKEN_LEN;
    char token_buf[TOKEN_LEN];
    TOKEN_USER *token_user = (TOKEN_USER*)token_buf;
    HANDLE tokenHandle;
    WCHAR domain[255 + 1 + 255 + 1];    // large enough to concat with '/' and name
    WCHAR name[255 + 1];
    DWORD domainLen = sizeof(domain) - sizeof(name);
    DWORD nameLen = sizeof(name);
    SID_NAME_USE use;
    jstring s;
    int ret;

    if (!OpenProcessToken(handle, TOKEN_READ, &tokenHandle)) {
        return;
    }

    ret = GetTokenInformation(tokenHandle, TokenUser, token_user,
                              token_len, &token_len);
    CloseHandle(tokenHandle);           // always close handle
    if (!ret) {
        JNU_ThrowByNameWithLastError(env,
            "java/lang/RuntimeException", "GetTokenInformation");
        return;
    }

    if (LookupAccountSidW(NULL, token_user->User.Sid, &name[0], &nameLen,
                          &domain[0], &domainLen, &use) == 0) {
        // Name not available, convert to a String
        LPWSTR str;
        if (ConvertSidToStringSidW(token_user->User.Sid, &str) == 0) {
            return;
        }
        s = (*env)->NewString(env, (const jchar *)str, (jsize)wcslen(str));
        LocalFree(str);
    } else {
        wcscat(domain, L"\\");
        wcscat(domain, name);
        s = (*env)->NewString(env, (const jchar *)domain, (jsize)wcslen(domain));
    }
    CHECK_NULL(s);
    (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_userID, s);
}
