Initial commit
Version 3.3 of the client
This commit is contained in:
175
src/com/sheepit/client/os/Linux.java
Normal file
175
src/com/sheepit/client/os/Linux.java
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
import com.sheepit.client.Log;
|
||||
import com.sheepit.client.Utils;
|
||||
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 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 > 0) {
|
||||
ret.setName(buf[1].trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (line.startsWith("cpu family")) {
|
||||
String buf[] = line.split(":");
|
||||
if (buf.length > 0) {
|
||||
ret.setFamily(buf[1].trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (line.startsWith("model") && line.startsWith("model name") == false) {
|
||||
String buf[] = line.split(":");
|
||||
if (buf.length > 0) {
|
||||
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 introducted by Java 5 and you are running are lower version");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int 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 are lower version");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCUDALib() {
|
||||
return "cuda";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process exec(String[] command) 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[0])).getParent() + File.separator + "lib";
|
||||
String new_ld_library_path = "/lib:/lib64:/usr/lib:/usr/lib64:/lib/i386-linux-gnu:/lib/x86_64-linux-gnu:/usr/share/local" + ":" + lib_dir;
|
||||
if (has_ld_library_path == false) {
|
||||
new_env.put("LD_LIBRARY_PATH", new_ld_library_path);
|
||||
}
|
||||
else {
|
||||
new_env.put("LD_LIBRARY_PATH", new_env.get("LD_LIBRARY_PATH") + ":" + new_ld_library_path);
|
||||
}
|
||||
|
||||
String[] actual_command = command;
|
||||
if (this.hasNiceBinary == null) {
|
||||
this.checkNiceAvailability();
|
||||
}
|
||||
if (this.hasNiceBinary.booleanValue()) {
|
||||
String[] low = { NICE_BINARY_PATH, "-n", "19" }; // launch the process in lowest priority
|
||||
actual_command = Utils.concatAll(low, command);
|
||||
}
|
||||
else {
|
||||
Log.getInstance(null).error("No low priority binary, will not launch renderer in normal prioity");
|
||||
}
|
||||
|
||||
ProcessBuilder builder = new ProcessBuilder(actual_command);
|
||||
builder.redirectErrorStream(true);
|
||||
Map<String, String> env = builder.environment();
|
||||
env.putAll(new_env);
|
||||
return builder.start();
|
||||
}
|
||||
|
||||
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 prioity (" + e + ")");
|
||||
}
|
||||
finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
178
src/com/sheepit/client/os/Mac.java
Normal file
178
src/com/sheepit/client/os/Mac.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import com.sheepit.client.Log;
|
||||
import com.sheepit.client.Utils;
|
||||
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 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 int 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 (int) (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 Process exec(String[] command) throws IOException {
|
||||
String[] actual_command = command;
|
||||
if (this.hasNiceBinary == null) {
|
||||
this.checkNiceAvailability();
|
||||
}
|
||||
if (this.hasNiceBinary.booleanValue()) {
|
||||
String[] low = { NICE_BINARY_PATH, "-n", "19" }; // launch the process in lowest priority
|
||||
actual_command = Utils.concatAll(low, command);
|
||||
}
|
||||
else {
|
||||
Log.getInstance(null).error("No low priority binary, will not launch renderer in normal prioity");
|
||||
}
|
||||
ProcessBuilder builder = new ProcessBuilder(actual_command);
|
||||
builder.redirectErrorStream(true);
|
||||
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 prioity (" + e + ")");
|
||||
}
|
||||
finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/com/sheepit/client/os/OS.java
Normal file
67
src/com/sheepit/client/os/OS.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 com.sheepit.client.hardware.cpu.CPU;
|
||||
|
||||
public abstract class OS {
|
||||
public String name() {
|
||||
return "others";
|
||||
}
|
||||
|
||||
public abstract CPU getCPU();
|
||||
|
||||
public abstract int getMemory();
|
||||
|
||||
public String getCUDALib() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Process exec(String[] command) throws IOException {
|
||||
ProcessBuilder builder = new ProcessBuilder(command);
|
||||
builder.redirectErrorStream(true);
|
||||
return builder.start();
|
||||
}
|
||||
|
||||
public boolean kill(Process proc) {
|
||||
if (proc != null) {
|
||||
proc.destroy();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static OS getOS() {
|
||||
String os = System.getProperty("os.name").toLowerCase();
|
||||
if (os.indexOf("win") >= 0) {
|
||||
return new Windows();
|
||||
}
|
||||
else if (os.indexOf("mac") >= 0) {
|
||||
return new Mac();
|
||||
}
|
||||
else if (os.indexOf("nix") >= 0 || os.indexOf("nux") >= 0) {
|
||||
return new Linux();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
138
src/com/sheepit/client/os/Windows.java
Normal file
138
src/com/sheepit/client/os/Windows.java
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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 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 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(new String(identifier[i + 1]));
|
||||
}
|
||||
if (identifier[i].equals("Model")) {
|
||||
ret.setModel(new String(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 int getMemory() {
|
||||
try {
|
||||
MEMORYSTATUSEX _memory = new MEMORYSTATUSEX();
|
||||
if (Kernel32.INSTANCE.GlobalMemoryStatusEx(_memory)) {
|
||||
return (int) (_memory.ullTotalPhys.longValue() / 1024); // size in KB
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCUDALib() {
|
||||
return "nvcuda";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process exec(String[] command) 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);
|
||||
Process p = builder.start();
|
||||
WinProcess wproc = new WinProcess(p);
|
||||
wproc.setPriority(WinProcess.PRIORITY_BELOW_NORMAL);
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean kill(Process process) {
|
||||
if (process != null) {
|
||||
WinProcess wproc = new WinProcess(process);
|
||||
wproc.kill();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
220
src/com/sheepit/client/os/windows/Kernel32Lib.java
Normal file
220
src/com/sheepit/client/os/windows/Kernel32Lib.java
Normal file
@@ -0,0 +1,220 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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);
|
||||
|
||||
}
|
||||
155
src/com/sheepit/client/os/windows/WinProcess.java
Normal file
155
src/com/sheepit/client/os/windows/WinProcess.java
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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.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);
|
||||
}
|
||||
}
|
||||
|
||||
public WinProcess(Process process) {
|
||||
this();
|
||||
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.handle = Kernel32.INSTANCE.OpenProcess(0x0400 | // PROCESS_QUERY_INFORMATION
|
||||
0x0800 | // PROCESS_SUSPEND_RESUME
|
||||
0x0001 | // PROCESS_TERMINATE
|
||||
0x0200 | // PROCESS_SET_INFORMATION
|
||||
0x00100000, // SYNCHRONIZE
|
||||
false, pid);
|
||||
if (this.handle == null) {
|
||||
throw new IOException("OpenProcess failed: " + Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE.GetLastError()) + " (pid: " + pid_ + ")");
|
||||
}
|
||||
this.pid = pid_;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
if (this.handle != null) {
|
||||
Kernel32.INSTANCE.CloseHandle(this.handle);
|
||||
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);
|
||||
}
|
||||
|
||||
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 + ")";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user