Moving to Intellij IDEA

This commit is contained in:
Laurent Clouet
2019-08-11 22:25:26 +02:00
parent 3001bed260
commit 3413301609
70 changed files with 60 additions and 322 deletions

View File

@@ -1,211 +0,0 @@
/*
* Copyright (C) 2010-2015 Laurent CLOUET
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sheepit.client.os;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import com.sheepit.client.Log;
import com.sheepit.client.hardware.cpu.CPU;
public class FreeBSD extends OS {
private final String NICE_BINARY_PATH = "nice";
private Boolean hasNiceBinary;
public FreeBSD() {
super();
this.hasNiceBinary = null;
}
public String name() {
return "freebsd";
}
@Override
public String getRenderBinaryPath() {
return "rend.exe";
}
@Override
public CPU getCPU() {
CPU ret = new CPU();
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec("dmesg");
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = b.readLine()) != null) {
if (line.startsWith("CPU:")) {
String buf[] = line.split(":");
if (buf.length > 1) {
ret.setName(buf[1].trim());
}
}
if (line.contains("Family=") && line.contains("Model=")) {
String buf[] = line.split(" ");
for (int i = 0; i < buf.length; i++) {
if (buf[i].contains("Family")) {
String family = buf[i].split("=")[1];
ret.setFamily(family.split("x")[1]);
}
if (buf[i].contains("Model")) {
String model = buf[i].split("=")[1];
ret.setModel(model.split("x")[1]);
}
}
}
}
b.close();
}
catch (Exception e) {
e.printStackTrace();
}
if (ret.haveData() == false) {
Log.getInstance(null).debug("OS::FreeBSD::getCPU failed to get CPU from dmesg, using partia sysctl");
ret.setModel("0");
ret.setFamily("0");
try {
Runtime run = Runtime.getRuntime();
Process sysctl = run.exec("sysctl -n hw.model");
BufferedReader buf = new BufferedReader(new InputStreamReader(sysctl.getInputStream()));
String name = "";
name = buf.readLine();
buf.close();
if (name == "") {
ret.setName("0");
}
else {
ret.setName(name);
}
}
catch (IOException e) {
Log.getInstance(null).debug("OS::FreeBSD::getCPU exception " + e);
}
}
return ret;
}
@Override
public long getMemory() {
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec("sysctl -n hw.usermem");
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
line = b.readLine();
b.close();
if (line.isEmpty()) {
return 0;
}
Long mem_byte = Long.parseLong(line.trim());
return mem_byte / Long.valueOf(1024);
}
catch (IOException e) {
Log.getInstance(null).debug("OS::FreeBSD::getMemory exception " + e);
}
return 0;
}
@Override
public long getFreeMemory() {
return -1;
}
@Override
public String getCUDALib() {
return "cuda";
}
@Override
public Process exec(List<String> command, Map<String, String> env_overight) throws IOException {
// the renderer have a lib directory so add to the LD_LIBRARY_PATH
// (even if we are not sure that it is the renderer who is launch
Map<String, String> new_env = new HashMap<String, String>();
new_env.putAll(java.lang.System.getenv()); // clone the env
Boolean has_ld_library_path = new_env.containsKey("LD_LIBRARY_PATH");
String lib_dir = (new File(command.get(0))).getParent() + File.separator + "lib";
if (has_ld_library_path == false) {
new_env.put("LD_LIBRARY_PATH", lib_dir);
}
else {
new_env.put("LD_LIBRARY_PATH", new_env.get("LD_LIBRARY_PATH") + ":" + lib_dir);
}
List<String> actual_command = command;
if (this.hasNiceBinary == null) {
this.checkNiceAvailability();
}
if (this.hasNiceBinary.booleanValue()) {
// launch the process in lowest priority
if (env_overight != null) {
actual_command.add(0, env_overight.get("PRIORITY"));
}
else {
actual_command.add(0, "19");
}
actual_command.add(0, "-n");
actual_command.add(0, NICE_BINARY_PATH);
}
else {
Log.getInstance(null).error("No low priority binary, will not launch renderer in normal priority");
}
ProcessBuilder builder = new ProcessBuilder(actual_command);
builder.redirectErrorStream(true);
Map<String, String> env = builder.environment();
env.putAll(new_env);
if (env_overight != null) {
env.putAll(env_overight);
}
return builder.start();
}
private void checkNiceAvailability() {
ProcessBuilder builder = new ProcessBuilder();
builder.command(NICE_BINARY_PATH);
builder.redirectErrorStream(true);
Process process = null;
try {
process = builder.start();
this.hasNiceBinary = true;
}
catch (IOException e) {
this.hasNiceBinary = false;
Log.getInstance(null).error("Failed to find low priority binary, will not launch renderer in normal priority (" + e + ")");
}
finally {
if (process != null) {
process.destroy();
}
}
}
}

View File

@@ -1,231 +0,0 @@
/*
* Copyright (C) 2010-2014 Laurent CLOUET
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sheepit.client.os;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import com.sheepit.client.Log;
import com.sheepit.client.hardware.cpu.CPU;
public class Linux extends OS {
private final String NICE_BINARY_PATH = "nice";
private Boolean hasNiceBinary;
public Linux() {
super();
this.hasNiceBinary = null;
}
public String name() {
return "linux";
}
@Override
public String getRenderBinaryPath() {
return "rend.exe";
}
@Override
public CPU getCPU() {
CPU ret = new CPU();
try {
String filePath = "/proc/cpuinfo";
Scanner scanner = new Scanner(new File(filePath));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("model name")) {
String buf[] = line.split(":");
if (buf.length > 1) {
ret.setName(buf[1].trim());
}
}
if (line.startsWith("cpu family")) {
String buf[] = line.split(":");
if (buf.length > 1) {
ret.setFamily(buf[1].trim());
}
}
if (line.startsWith("model") && line.startsWith("model name") == false) {
String buf[] = line.split(":");
if (buf.length > 1) {
ret.setModel(buf[1].trim());
}
}
}
scanner.close();
}
catch (java.lang.NoClassDefFoundError e) {
System.err.println("OS.Linux::getCPU error " + e + " mostly because Scanner class was introduced by Java 5 and you are running a lower version");
}
catch (Exception e) {
e.printStackTrace();
}
return ret;
}
@Override
public long getMemory() {
try {
String filePath = "/proc/meminfo";
Scanner scanner = new Scanner(new File(filePath));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("MemTotal")) {
String buf[] = line.split(":");
if (buf.length > 0) {
Integer buf2 = new Integer(buf[1].trim().split(" ")[0]);
return (((buf2 / 262144) + 1) * 262144); // 256*1024 = 262144
}
}
}
scanner.close();
}
catch (java.lang.NoClassDefFoundError e) {
System.err.println("Machine::type error " + e + " mostly because Scanner class was introducted by Java 5 and you are running a lower version");
}
catch (Exception e) {
e.printStackTrace();
}
return 0;
}
@Override
public long getFreeMemory() {
try {
String filePath = "/proc/meminfo";
Scanner scanner = new Scanner(new File(filePath));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("MemAvailable")) {
String buf[] = line.split(":");
if (buf.length > 0) {
Integer buf2 = new Integer(buf[1].trim().split(" ")[0]);
return (((buf2 / 262144) + 1) * 262144); // 256*1024 = 262144
}
}
}
scanner.close();
}
catch (java.lang.NoClassDefFoundError e) {
System.err.println("OS::Linux::getFreeMemory error " + e + " mostly because Scanner class was introducted by Java 5 and you are running a lower version");
}
catch (Exception e) {
e.printStackTrace();
}
return 0;
}
@Override
public String getCUDALib() {
return "cuda";
}
@Override
public Process exec(List<String> command, Map<String, String> env_overight) throws IOException {
// the renderer have a lib directory so add to the LD_LIBRARY_PATH
// (even if we are not sure that it is the renderer who is launch
Map<String, String> new_env = new HashMap<String, String>();
new_env.putAll(java.lang.System.getenv()); // clone the env
Boolean has_ld_library_path = new_env.containsKey("LD_LIBRARY_PATH");
String lib_dir = (new File(command.get(0))).getParent() + File.separator + "lib";
if (has_ld_library_path == false) {
new_env.put("LD_LIBRARY_PATH", lib_dir);
}
else {
new_env.put("LD_LIBRARY_PATH", new_env.get("LD_LIBRARY_PATH") + ":" + lib_dir);
}
List<String> actual_command = command;
if (this.hasNiceBinary == null) {
this.checkNiceAvailability();
}
if (this.hasNiceBinary.booleanValue()) {
// launch the process in lowest priority
if (env_overight != null) {
actual_command.add(0, env_overight.get("PRIORITY"));
}
else {
actual_command.add(0, "19");
}
actual_command.add(0, "-n");
actual_command.add(0, NICE_BINARY_PATH);
}
else {
Log.getInstance(null).error("No low priority binary, will not launch renderer in normal priority");
}
ProcessBuilder builder = new ProcessBuilder(actual_command);
builder.redirectErrorStream(true);
Map<String, String> env = builder.environment();
env.putAll(new_env);
if (env_overight != null) {
env.putAll(env_overight);
}
return builder.start();
}
@Override
public boolean getSupportHighPriority() {
// only the root user can create process with high (negative nice) value
String logname = System.getenv("LOGNAME");
String user = System.getenv("USER");
if ((logname != null && logname.equals("root")) || (user != null && user.equals("root"))) {
return true;
}
return false;
}
protected void checkNiceAvailability() {
ProcessBuilder builder = new ProcessBuilder();
builder.command(NICE_BINARY_PATH);
builder.redirectErrorStream(true);
Process process = null;
try {
process = builder.start();
this.hasNiceBinary = true;
}
catch (IOException e) {
this.hasNiceBinary = false;
Log.getInstance(null).error("Failed to find low priority binary, will not launch renderer in normal priority (" + e + ")");
}
finally {
if (process != null) {
process.destroy();
}
}
}
}

View File

@@ -1,200 +0,0 @@
/*
* Copyright (C) 2010-2014 Laurent CLOUET
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sheepit.client.os;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import com.sheepit.client.Log;
import com.sheepit.client.hardware.cpu.CPU;
public class Mac extends OS {
private final String NICE_BINARY_PATH = "nice";
private Boolean hasNiceBinary;
public Mac() {
super();
this.hasNiceBinary = null;
}
public String name() {
return "mac";
}
@Override
public String getRenderBinaryPath() {
return "Blender" + File.separator + "blender.app" + File.separator + "Contents" + File.separator + "MacOS" + File.separator + "blender";
}
@Override
public CPU getCPU() {
CPU ret = new CPU();
String command = "sysctl machdep.cpu.family machdep.cpu.brand_string";
Process p = null;
BufferedReader input = null;
try {
String line;
p = Runtime.getRuntime().exec(command);
input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
String option_cpu_family = "machdep.cpu.family:";
String option_model_name = "machdep.cpu.brand_string:";
if (line.startsWith(option_model_name)) {
ret.setName(line.substring(option_model_name.length()).trim());
}
if (line.startsWith(option_cpu_family)) {
ret.setFamily(line.substring(option_cpu_family.length()).trim());
}
}
input.close();
input = null;
}
catch (Exception err) {
System.out.println("exception " + err);
err.printStackTrace();
ret.setName("Unknown Mac name");
ret.setFamily("Unknown Mac family");
}
finally {
if (input != null) {
try {
input.close();
}
catch (IOException e) {
}
}
if (p != null) {
p.destroy();
}
}
ret.setModel("Unknown");
return ret;
}
@Override
public long getMemory() {
String command = "sysctl hw.memsize";
Process p = null;
BufferedReader input = null;
try {
String line;
p = Runtime.getRuntime().exec(command);
input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
String option = "hw.memsize:";
if (line.startsWith(option)) {
String memory = line.substring(option.length()).trim(); // memory in bytes
return Long.parseLong(memory) / 1024;
}
}
input.close();
input = null;
}
catch (Exception err) {
System.out.println("exception " + err);
err.printStackTrace();
}
finally {
if (input != null) {
try {
input.close();
}
catch (IOException e) {
}
}
if (p != null) {
p.destroy();
}
}
return -1;
}
@Override
public long getFreeMemory() {
return -1;
}
@Override
public Process exec(List<String> command, Map<String, String> env) throws IOException {
List<String> actual_command = command;
if (this.hasNiceBinary == null) {
this.checkNiceAvailability();
}
if (this.hasNiceBinary.booleanValue()) {
// launch the process in lowest priority
if (env != null) {
actual_command.add(0, env.get("PRIORITY"));
}
else {
actual_command.add(0, "19");
}
actual_command.add(0, "-n");
actual_command.add(0, NICE_BINARY_PATH);
}
else {
Log.getInstance(null).error("No low priority binary, will not launch renderer in normal priority");
}
ProcessBuilder builder = new ProcessBuilder(actual_command);
builder.redirectErrorStream(true);
if (env != null) {
builder.environment().putAll(env);
}
return builder.start();
}
@Override
public String getCUDALib() {
return "/usr/local/cuda/lib/libcuda.dylib";
}
protected void checkNiceAvailability() {
ProcessBuilder builder = new ProcessBuilder();
builder.command(NICE_BINARY_PATH);
builder.redirectErrorStream(true);
Process process = null;
try {
process = builder.start();
this.hasNiceBinary = true;
}
catch (IOException e) {
this.hasNiceBinary = false;
Log.getInstance(null).error("Failed to find low priority binary, will not launch renderer in normal priority (" + e + ")");
}
finally {
if (process != null) {
process.destroy();
}
}
}
}

View File

@@ -1,84 +0,0 @@
/*
* Copyright (C) 2010-2014 Laurent CLOUET
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sheepit.client.os;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import com.sheepit.client.hardware.cpu.CPU;
public abstract class OS {
private static OS instance = null;
public abstract String name();
public abstract CPU getCPU();
public abstract long getMemory();
public abstract long getFreeMemory();
public abstract String getRenderBinaryPath();
public String getCUDALib() {
return null;
}
public boolean getSupportHighPriority() {
return true;
}
public Process exec(List<String> command, Map<String, String> env) throws IOException {
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
if (env != null) {
builder.environment().putAll(env);
}
return builder.start();
}
public boolean kill(Process proc) {
if (proc != null) {
proc.destroy();
return true;
}
return false;
}
public static OS getOS() {
if (instance == null) {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
instance = new Windows();
}
else if (os.contains("mac")) {
instance = new Mac();
}
else if (os.contains("nix") || os.contains("nux")) {
instance = new Linux();
}
else if (os.contains("freebsd")) {
instance = new FreeBSD();
}
}
return instance;
}
}

View File

@@ -1,228 +0,0 @@
/*
* Copyright (C) 2010-2014 Laurent CLOUET
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sheepit.client.os;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import com.sheepit.client.hardware.cpu.CPU;
import com.sheepit.client.os.windows.Kernel32Lib;
import com.sheepit.client.os.windows.WinProcess;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinBase.MEMORYSTATUSEX;
import com.sun.jna.platform.win32.WinReg;
public class Windows extends OS {
public String name() {
return "windows";
}
@Override
public String getRenderBinaryPath() {
return "rend.exe";
}
@Override
public CPU getCPU() {
CPU ret = new CPU();
try {
String[] identifier = java.lang.System.getenv("PROCESSOR_IDENTIFIER").split(" ");
for (int i = 0; i < (identifier.length - 1); i++) {
if (identifier[i].equals("Family")) {
ret.setFamily(identifier[i + 1]);
}
if (identifier[i].equals("Model")) {
ret.setModel(identifier[i + 1]);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
try {
final String cpuRegistryRoot = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor";
String[] processorIds = Advapi32Util.registryGetKeys(WinReg.HKEY_LOCAL_MACHINE, cpuRegistryRoot);
if (processorIds.length > 0) {
String processorId = processorIds[0];
String cpuRegistryPath = cpuRegistryRoot + "\\" + processorId;
ret.setName(Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, cpuRegistryPath, "ProcessorNameString").trim());
}
}
catch (Exception e) {
e.printStackTrace();
}
// override the arch
String env_arch = java.lang.System.getenv("PROCESSOR_ARCHITEW6432");
if (env_arch == null || env_arch.compareTo("") == 0) {
env_arch = java.lang.System.getenv("PROCESSOR_ARCHITECTURE");
}
if (env_arch.compareTo("AMD64") == 0) {
ret.setArch("64bit");
}
else {
ret.setArch("32bit");
}
return ret;
}
@Override
public long getMemory() {
try {
MEMORYSTATUSEX _memory = new MEMORYSTATUSEX();
if (Kernel32.INSTANCE.GlobalMemoryStatusEx(_memory)) {
return _memory.ullTotalPhys.longValue() / 1024; // size in KB
}
}
catch (Exception e) {
e.printStackTrace();
}
return 0;
}
@Override
public long getFreeMemory() {
try {
MEMORYSTATUSEX _memory = new MEMORYSTATUSEX();
if (Kernel32.INSTANCE.GlobalMemoryStatusEx(_memory)) {
return _memory.ullAvailPhys.longValue() / 1024; // size in KB
}
}
catch (Exception e) {
e.printStackTrace();
}
return -1;
}
@Override
public String getCUDALib() {
return "nvcuda";
}
@Override
public Process exec(List<String> command, Map<String, String> env) throws IOException {
// disable a popup because the renderer might crash (seg fault)
Kernel32Lib kernel32lib = null;
try {
kernel32lib = (Kernel32Lib) Native.loadLibrary(Kernel32Lib.path, Kernel32Lib.class);
kernel32lib.SetErrorMode(Kernel32Lib.SEM_NOGPFAULTERRORBOX);
}
catch (java.lang.UnsatisfiedLinkError e) {
System.out.println("OS.Windows::exec failed to load kernel32lib " + e);
}
catch (java.lang.ExceptionInInitializerError e) {
System.out.println("OS.Windows::exec failed to load kernel32lib " + e);
}
catch (Exception e) {
System.out.println("OS.Windows::exec failed to load kernel32lib " + e);
}
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
if (env != null) {
builder.environment().putAll(env);
}
Process p = builder.start();
WinProcess wproc = new WinProcess(p);
if (env != null) {
String priority = env.get("PRIORITY");
wproc.setPriority(getPriorityClass(Integer.parseInt(priority)));
}
else {
wproc.setPriority(WinProcess.PRIORITY_BELOW_NORMAL);
}
return p;
}
int getPriorityClass(int priority) {
int process_class = WinProcess.PRIORITY_IDLE;
switch (priority) {
case 19:
case 18:
case 17:
case 16:
case 15:
process_class = WinProcess.PRIORITY_IDLE;
break;
case 14:
case 13:
case 12:
case 11:
case 10:
case 9:
case 8:
case 7:
case 6:
case 5:
process_class = WinProcess.PRIORITY_BELOW_NORMAL;
break;
case 4:
case 3:
case 2:
case 1:
case 0:
case -1:
case -2:
case -3:
process_class = WinProcess.PRIORITY_NORMAL;
break;
case -4:
case -5:
case -6:
case -7:
case -8:
case -9:
process_class = WinProcess.PRIORITY_ABOVE_NORMAL;
break;
case -10:
case -11:
case -12:
case -13:
case -14:
process_class = WinProcess.PRIORITY_HIGH;
break;
case -15:
case -16:
case -17:
case -18:
case -19:
process_class = WinProcess.PRIORITY_REALTIME;
break;
}
return process_class;
}
@Override
public boolean kill(Process process) {
if (process != null) {
WinProcess wproc = new WinProcess(process);
wproc.kill();
return true;
}
return false;
}
}

View File

@@ -1,214 +0,0 @@
/* This file was originally taken from JNA project (https://github.com/twall/jna)
* filename: contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java
*
* 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.
*/
package com.sheepit.client.os.windows;
import java.util.Arrays;
import java.util.List;
import com.sun.jna.Library;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.BaseTSD;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.platform.win32.WinNT.HANDLE;
public interface Kernel32Lib extends Library {
public static final String path = "kernel32";
/**
* Includes all heaps of the process specified in th32ProcessID in the snapshot. To enumerate the heaps, see
* Heap32ListFirst.
*/
WinDef.DWORD TH32CS_SNAPHEAPLIST = new WinDef.DWORD(0x00000001);
/**
* Includes all processes in the system in the snapshot. To enumerate the processes, see Process32First.
*/
WinDef.DWORD TH32CS_SNAPPROCESS = new WinDef.DWORD(0x00000002);
/**
* Includes all threads in the system in the snapshot. To enumerate the threads, see Thread32First.
*/
WinDef.DWORD TH32CS_SNAPTHREAD = new WinDef.DWORD(0x00000004);
/**
* Includes all modules of the process specified in th32ProcessID in the snapshot. To enumerate the modules, see
* Module32First. If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds.
*/
WinDef.DWORD TH32CS_SNAPMODULE = new WinDef.DWORD(0x00000008);
/**
* Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit
* process. This flag can be combined with TH32CS_SNAPMODULE or TH32CS_SNAPALL. If the function fails with
* ERROR_BAD_LENGTH, retry the function until it succeeds.
*/
WinDef.DWORD TH32CS_SNAPMODULE32 = new WinDef.DWORD(0x00000010);
/**
* Includes all processes and threads in the system, plus the heaps and modules of the process specified in th32ProcessID.
*/
WinDef.DWORD TH32CS_SNAPALL = new WinDef.DWORD((TH32CS_SNAPHEAPLIST.intValue() | TH32CS_SNAPPROCESS.intValue() | TH32CS_SNAPTHREAD.intValue() | TH32CS_SNAPMODULE.intValue()));
/**
* Indicates that the snapshot handle is to be inheritable.
*/
WinDef.DWORD TH32CS_INHERIT = new WinDef.DWORD(0x80000000);
/**
* The system does not display the Windows Error Reporting dialog.
* See: http://msdn.microsoft.com/en-us/library/ms680621%28VS.85%29.aspx
*/
WinDef.DWORD SEM_NOGPFAULTERRORBOX = new WinDef.DWORD(0x0002);
/**
* Describes an entry from a list of the processes residing in the system address space when a snapshot was taken.
*/
public static class PROCESSENTRY32 extends Structure {
public static class ByReference extends PROCESSENTRY32 implements Structure.ByReference {
public ByReference() {
}
public ByReference(Pointer memory) {
super(memory);
}
}
public PROCESSENTRY32() {
dwSize = new WinDef.DWORD(size());
}
public PROCESSENTRY32(Pointer memory) {
useMemory(memory);
read();
}
/**
* The size of the structure, in bytes. Before calling the Process32First function, set this member to
* sizeof(PROCESSENTRY32). If you do not initialize dwSize, Process32First fails.
*/
public WinDef.DWORD dwSize;
/**
* This member is no longer used and is always set to zero.
*/
public WinDef.DWORD cntUsage;
/**
* The process identifier.
*/
public WinDef.DWORD th32ProcessID;
/**
* This member is no longer used and is always set to zero.
*/
public BaseTSD.ULONG_PTR th32DefaultHeapID;
/**
* This member is no longer used and is always set to zero.
*/
public WinDef.DWORD th32ModuleID;
/**
* The number of execution threads started by the process.
*/
public WinDef.DWORD cntThreads;
/**
* The identifier of the process that created this process (its parent process).
*/
public WinDef.DWORD th32ParentProcessID;
/**
* The base priority of any threads created by this process.
*/
public WinDef.LONG pcPriClassBase;
/**
* This member is no longer used, and is always set to zero.
*/
public WinDef.DWORD dwFlags;
/**
* The name of the executable file for the process. To retrieve the full path to the executable file, call the
* Module32First function and check the szExePath member of the MODULEENTRY32 structure that is returned.
* However, if the calling process is a 32-bit process, you must call the QueryFullProcessImageName function to
* retrieve the full path of the executable file for a 64-bit process.
*/
public char[] szExeFile = new char[WinDef.MAX_PATH];
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "dwSize", "cntUsage", "th32ProcessID", "th32DefaultHeapID", "th32ModuleID", "cntThreads", "th32ParentProcessID", "pcPriClassBase", "dwFlags", "szExeFile" });
}
}
/**
* Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes.
*
* @param dwFlags The portions of the system to be included in the snapshot.
* @param th32ProcessID The process identifier of the process to be included in the snapshot. This parameter can be zero to indicate
* the current process. This parameter is used when the TH32CS_SNAPHEAPLIST, TH32CS_SNAPMODULE,
* TH32CS_SNAPMODULE32, or TH32CS_SNAPALL value is specified. Otherwise, it is ignored and all processes are
* included in the snapshot.
* <p/>
* If the specified process is the Idle process or one of the CSRSS processes, this function fails and the last
* error code is ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from opening them.
* <p/>
* If the specified process is a 64-bit process and the caller is a 32-bit process, this function fails and the
* last error code is ERROR_PARTIAL_COPY (299).
* @return If the function succeeds, it returns an open handle to the specified snapshot.
* <p/>
* If the function fails, it returns INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.
* Possible error codes include ERROR_BAD_LENGTH.
*/
public WinNT.HANDLE CreateToolhelp32Snapshot(WinDef.DWORD dwFlags, WinDef.DWORD th32ProcessID);
/**
* Retrieves information about the first process encountered in a system snapshot.
*
* @param hSnapshot A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
* @param lppe A pointer to a PROCESSENTRY32 structure. It contains process information such as the name of the
* executable file, the process identifier, and the process identifier of the parent process.
* @return Returns TRUE if the first entry of the process list has been copied to the buffer or FALSE otherwise. The
* ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no processes exist or the snapshot
* does not contain process information.
*/
public boolean Process32First(WinNT.HANDLE hSnapshot, Kernel32Lib.PROCESSENTRY32.ByReference lppe);
/**
* Retrieves information about the next process recorded in a system snapshot.
*
* @param hSnapshot A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
* @param lppe A pointer to a PROCESSENTRY32 structure.
* @return Returns TRUE if the next entry of the process list has been copied to the buffer or FALSE otherwise. The
* ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no processes exist or the snapshot
* does not contain process information.
*/
public boolean Process32Next(WinNT.HANDLE hSnapshot, Kernel32Lib.PROCESSENTRY32.ByReference lppe);
public boolean SetPriorityClass(HANDLE hProcess, int dwPriorityClass);
/**
* Controls whether the system will handle the specified types of serious errors or whether the process will handle them.
* See: http://msdn.microsoft.com/en-us/library/ms680621%28VS.85%29.aspx
*
* @param uMode The process error mode. This parameter can be one or more of the following values.
*/
public int SetErrorMode(DWORD uMode);
}

View File

@@ -1,194 +0,0 @@
/*
* Copyright (C) 2013 Laurent CLOUET
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sheepit.client.os.windows;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinNT;
public class WinProcess {
public static final int PRIORITY_IDLE = 0x40;
public static final int PRIORITY_BELOW_NORMAL = 0x4000;
public static final int PRIORITY_NORMAL = 0x20;
public static final int PRIORITY_ABOVE_NORMAL = 0x8000;
public static final int PRIORITY_HIGH = 0x80;
public static final int PRIORITY_REALTIME = 0x100;
private WinNT.HANDLE handle;
private int pid;
Kernel32Lib kernel32lib;
public WinProcess() {
this.handle = null;
this.pid = -1;
this.kernel32lib = null;
try {
this.kernel32lib = (Kernel32Lib) Native.loadLibrary(Kernel32Lib.path, Kernel32Lib.class);
}
catch (java.lang.UnsatisfiedLinkError e) {
System.out.println("WinProcess::construct " + e);
}
catch (java.lang.ExceptionInInitializerError e) {
System.out.println("WinProcess::construct " + e);
}
catch (Exception e) {
System.out.println("WinProcess::construct " + e);
}
}
private static boolean processHasGetPid() {
try {
if (Process.class.getMethod("pid", null) != null) {
return true;
}
}
catch (NoSuchMethodException | SecurityException e) {
}
return false;
}
private static long getPid(Process process) {
try {
return (long) Process.class.getMethod("pid", null).invoke(process, null);
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
}
return 0;
}
private static WinNT.HANDLE getHandleByPid(int pid_) throws IOException {
WinNT.HANDLE handle = Kernel32.INSTANCE.OpenProcess(0x0400 | // PROCESS_QUERY_INFORMATION
0x0800 | // PROCESS_SUSPEND_RESUME
0x0001 | // PROCESS_TERMINATE
0x0200 | // PROCESS_SET_INFORMATION
0x00100000, // SYNCHRONIZE
false, pid_);
if (handle == null) {
throw new IOException("OpenProcess failed: " + Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE.GetLastError()) + " (pid: " + pid_ + ")");
}
return handle;
}
public WinProcess(Process process) {
this();
if (processHasGetPid()) {
int _pid = (int) getPid(process);
try {
this.handle = getHandleByPid(_pid);
}
catch (IOException e) {
}
this.pid = _pid;
}
else {
try {
Field f = process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long val = f.getLong(process);
this.handle = new WinNT.HANDLE();
this.handle.setPointer(Pointer.createConstant(val));
this.pid = Kernel32.INSTANCE.GetProcessId(this.handle);
}
catch (NoSuchFieldException e) {
}
catch (IllegalArgumentException e) {
}
catch (IllegalAccessException e) {
}
}
}
public WinProcess(int pid_) throws IOException {
this();
this.handle = getHandleByPid(pid_);
this.pid = pid_;
}
@Override
protected void finalize() throws Throwable {
if (this.handle != null) {
// Kernel32.INSTANCE.CloseHandle(this.handle); // do not close the handle because the parent Process object might still be alive
this.handle = null;
}
this.pid = -1;
}
public boolean kill() {
try {
List<WinProcess> children = this.getChildren();
this.terminate();
for (WinProcess child : children) {
child.kill();
}
}
catch (IOException e) {
e.printStackTrace();
}
return false;
}
public boolean setPriority(int priority) {
return this.kernel32lib.SetPriorityClass(this.handle, priority);
}
private void terminate() {
Kernel32.INSTANCE.TerminateProcess(this.handle, 0);
Kernel32.INSTANCE.CloseHandle(this.handle); // we are sure that the parent Process object is dead
}
private List<WinProcess> getChildren() throws IOException {
ArrayList<WinProcess> result = new ArrayList<WinProcess>();
WinNT.HANDLE hSnap = this.kernel32lib.CreateToolhelp32Snapshot(Kernel32Lib.TH32CS_SNAPPROCESS, new DWORD(0));
Kernel32Lib.PROCESSENTRY32.ByReference ent = new Kernel32Lib.PROCESSENTRY32.ByReference();
if (!this.kernel32lib.Process32First(hSnap, ent)) {
return result;
}
do {
if (ent.th32ParentProcessID.intValue() == this.pid) {
try {
result.add(new WinProcess(ent.th32ProcessID.intValue()));
}
catch (IOException e) {
System.err.println("WinProcess::getChildren, IOException " + e);
}
}
}
while (this.kernel32lib.Process32Next(hSnap, ent));
Kernel32.INSTANCE.CloseHandle(hSnap);
return result;
}
public String toString() {
return "WinProcess(pid: " + this.pid + ", handle " + this.handle + ")";
}
}