diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java b/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java
index 9457ae2cf..3e5de7968 100644
--- a/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java
+++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java
@@ -473,7 +473,7 @@ public class Helper {
}
}
} catch (IOException ex) {
- Logger.getLogger(Helper.class.getName()).log(Level.SEVERE, null, ex);
+ //ignore
}
}
diff --git a/src/com/jpexs/process/win32/Win32ProcessTools.java b/src/com/jpexs/process/win32/Win32ProcessTools.java
index a2376719e..a51d129ef 100644
--- a/src/com/jpexs/process/win32/Win32ProcessTools.java
+++ b/src/com/jpexs/process/win32/Win32ProcessTools.java
@@ -1,605 +1,606 @@
-/*
- * Copyright (C) 2010-2014 JPEXS
- *
- * 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, either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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, see .
- */
-package com.jpexs.process.win32;
-
-import com.jpexs.helpers.ProgressListener;
-import com.jpexs.process.ProcessTools;
-import com.sun.jna.Memory;
-import com.sun.jna.NativeLong;
-import com.sun.jna.Pointer;
-import com.sun.jna.platform.win32.Advapi32;
-import com.sun.jna.platform.win32.BITMAP;
-import com.sun.jna.platform.win32.BaseTSD;
-import com.sun.jna.platform.win32.Gdi32;
-import com.sun.jna.platform.win32.ICONINFO;
-import com.sun.jna.platform.win32.Kernel32;
-import com.sun.jna.platform.win32.MEMORY_BASIC_INFORMATION;
-import com.sun.jna.platform.win32.PROCESSENTRY32;
-import com.sun.jna.platform.win32.Psapi;
-import com.sun.jna.platform.win32.SHFILEINFO;
-import com.sun.jna.platform.win32.Shell32;
-import com.sun.jna.platform.win32.User32;
-import com.sun.jna.platform.win32.WinBase;
-import com.sun.jna.platform.win32.WinDef;
-import com.sun.jna.platform.win32.WinNT;
-import com.sun.jna.platform.win32.WinNT.HANDLE;
-import com.sun.jna.ptr.IntByReference;
-import com.sun.jna.ptr.PointerByReference;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- *
- * @author JPEXS
- */
-public class Win32ProcessTools extends ProcessTools {
-
- private static long pointerToAddress(Pointer p) {
- String s = p.toString();
- s = s.replace("native@0x", "");
- return Long.parseLong(s, 16);
- }
-
- public static List getPageRanges(WinNT.HANDLE hOtherProcess) {
- List ret = new ArrayList<>();
- MEMORY_BASIC_INFORMATION mbi;
- WinBase.SYSTEM_INFO si = new WinBase.SYSTEM_INFO();
- Kernel32.INSTANCE.GetSystemInfo(si);
- Pointer lpMem = si.lpMinimumApplicationAddress;
- while (pointerToAddress(lpMem) < pointerToAddress(si.lpMaximumApplicationAddress)) {
- mbi = new MEMORY_BASIC_INFORMATION();
- BaseTSD.SIZE_T t = Kernel32.INSTANCE.VirtualQueryEx(hOtherProcess, lpMem, mbi, new BaseTSD.SIZE_T(mbi.size()));
- if (t.longValue() == 0) {
- Logger.getLogger(Win32ProcessTools.class.getName()).log(Level.SEVERE, "Cannot get page ranges. Last error:" + Kernel32.INSTANCE.GetLastError());
- break;
- }
- ret.add(mbi);
- lpMem = new Pointer(pointerToAddress(mbi.baseAddress) + mbi.regionSize.longValue());
- }
- return ret;
- }
-
- public static void printMemInfo(MEMORY_BASIC_INFORMATION mbi) {
- System.out.println("Region size:" + mbi.regionSize);
- String stateStr = "";
- if ((mbi.state.intValue() & Kernel32.MEM_COMMIT) == Kernel32.MEM_COMMIT) {
- stateStr += " commit";
- }
- if ((mbi.state.intValue() & Kernel32.MEM_FREE) == Kernel32.MEM_FREE) {
- stateStr += " free";
- }
- if ((mbi.state.intValue() & Kernel32.MEM_RESERVE) == Kernel32.MEM_RESERVE) {
- stateStr += " reserve";
- }
- stateStr = stateStr.trim();
-
- String typeStr = "";
- if ((mbi.type.intValue() & Kernel32.MEM_IMAGE) == Kernel32.MEM_IMAGE) {
- typeStr += " image";
- }
- if ((mbi.type.intValue() & Kernel32.MEM_MAPPED) == Kernel32.MEM_MAPPED) {
- typeStr += " mapped";
- }
- if ((mbi.type.intValue() & Kernel32.MEM_PRIVATE) == Kernel32.MEM_PRIVATE) {
- typeStr += " private";
- }
- typeStr = typeStr.trim();
-
- String protStr = "";
- if ((mbi.allocationProtect.intValue() & WinNT.PAGE_EXECUTE) == Kernel32.PAGE_EXECUTE) {
- protStr += " execute";
- }
- if ((mbi.allocationProtect.intValue() & WinNT.PAGE_EXECUTE_READ) == Kernel32.PAGE_EXECUTE_READ) {
- protStr += " execute_read";
- }
- if ((mbi.allocationProtect.intValue() & WinNT.PAGE_EXECUTE_READWRITE) == Kernel32.PAGE_EXECUTE_READWRITE) {
- protStr += " execute_readwrite";
- }
- if ((mbi.allocationProtect.intValue() & WinNT.PAGE_READONLY) == Kernel32.PAGE_READONLY) {
- protStr += " readonly";
- }
- if ((mbi.allocationProtect.intValue() & WinNT.PAGE_READWRITE) == Kernel32.PAGE_READWRITE) {
- protStr += " readwrite";
- }
- if ((mbi.allocationProtect.intValue() & WinNT.PAGE_WRITECOPY) == Kernel32.PAGE_WRITECOPY) {
- protStr += " writecopy";
- }
-
- protStr = protStr.trim();
- System.out.println("State:" + stateStr);
- System.out.println("Type:" + typeStr);
- System.out.println("Protect:" + protStr);
- System.out.println("baseAddress:" + mbi.baseAddress);
- System.out.println("========================");
- }
-
- private static byte[] mergeArrays(byte[] one, byte[] two) {
- byte[] combined = new byte[one.length + two.length];
-
- System.arraycopy(one, 0, combined, 0, one.length);
- System.arraycopy(two, 0, combined, one.length, two.length);
- return combined;
- }
-
- public static Map getDriveMappings() {
- Map ret = new HashMap<>();
- for (char d = 'A'; d <= 'Z'; d++) {
- char[] buf = new char[1024];
- int len = Kernel32.INSTANCE.QueryDosDevice("" + d + ":", buf, buf.length).intValue();
- String tar = new String(buf, 0, len);
- tar = tar.trim();
- if (!"".equals(tar)) {
- ret.put(tar, d);
- }
- }
- return ret;
- }
-
- public static String ntPathToWin32(String path) {
- for (String dp : driveMappings.keySet()) {
- if (path.startsWith(dp)) {
- return driveMappings.get(dp) + ":" + path.substring(dp.length());
- }
- }
- return path;
- }
- private static final Map driveMappings = getDriveMappings();
-
- public static boolean drawIcon(BufferedImage ret, WinDef.HICON hIcon, int diFlags) {
-
- WinDef.HDC hdcScreen = User32.INSTANCE.GetDC(null);
- WinDef.HDC hdcMem = Gdi32.INSTANCE.CreateCompatibleDC(hdcScreen);
-
- WinDef.HBITMAP bitmap = Gdi32.INSTANCE.CreateCompatibleBitmap(hdcScreen, ret.getWidth(), ret.getHeight());
-
- WinNT.HANDLE hbmOld = Gdi32.INSTANCE.SelectObject(hdcMem, bitmap);
-
- WinNT.HANDLE hBrush = Gdi32.INSTANCE.CreateSolidBrush(new WinDef.DWORD(0xffffff));
- WinDef.RECT rect = new WinDef.RECT();
- rect.left = 0;
- rect.top = 0;
- rect.right = ret.getWidth();
- rect.bottom = ret.getHeight();
- User32.INSTANCE.FillRect(hdcMem, rect, hBrush);
- Gdi32.INSTANCE.DeleteObject(hBrush);
-
- boolean ok = User32.INSTANCE.DrawIconEx(hdcMem, 0, 0, hIcon, ret.getWidth(), ret.getHeight(), new WinDef.UINT(0), new WinDef.HBRUSH(Pointer.NULL), diFlags);
-
- if (!ok) {
- return false;
- }
-
- for (int x = 0; x < ret.getWidth(); x++) {
- for (int y = 0; y < ret.getHeight(); y++) {
- int rgb = Gdi32.INSTANCE.GetPixel(hdcMem, x, y).intValue();
- int r = (rgb >> 16) & 0xff;
- int g = (rgb >> 8) & 0xff;
- int b = (rgb) & 0xff;
- rgb = (b << 16) + (g << 8) + r;
- ret.setRGB(x, y, rgb);
- }
- }
-
- Gdi32.INSTANCE.SelectObject(hdcMem, hbmOld);
- Gdi32.INSTANCE.DeleteObject(bitmap);
- Gdi32.INSTANCE.DeleteDC(hdcMem);
- User32.INSTANCE.ReleaseDC(null, hdcScreen);
- return true;
- }
-
- private static void applyMask(BufferedImage image, BufferedImage mask) {
- int width = image.getWidth();
- int height = image.getHeight();
- for (int x = 0; x < width; x++) {
- for (int y = 0; y < height; y++) {
- int masked = mask.getRGB(x, y);
- int alpha = 255 - (masked & 0xff);
- if (alpha != 0 && alpha != 255) {
- System.out.println("a=" + alpha);
- }
- int rgb = image.getRGB(x, y);
- int r = (rgb >> 16) & 0xff;
- int g = (rgb >> 8) & 0xff;
- int b = (rgb) & 0xff;
- r = r * alpha / 255;
- g = g * alpha / 255;
- b = b * alpha / 255;
-
- rgb = (r << 16) + (g << 8) + b;
-
- rgb = (alpha << 24) | rgb;
- image.setRGB(x, y, rgb);
- }
- }
- }
-
- public static BufferedImage iconToImage(WinDef.HICON hIcon) {
- ICONINFO info = new ICONINFO();
- boolean ok = User32.INSTANCE.GetIconInfo(hIcon, info);
- if (!ok) {
- return null;
- }
- BufferedImage ret = null;
- BITMAP bmp = new BITMAP();
- if (info.hbmColor != null) {
- int nWrittenBytes = Gdi32.INSTANCE.GetObject(info.hbmColor, bmp.size(), bmp);
- if (nWrittenBytes > 0) {
- ret = new BufferedImage(bmp.bmWidth.intValue(), bmp.bmHeight.intValue(), BufferedImage.TYPE_INT_ARGB);
- }
- } else if (info.hbmMask != null) {
- int nWrittenBytes = Gdi32.INSTANCE.GetObject(info.hbmMask, bmp.size(), bmp);
- if (nWrittenBytes > 0) {
- ret = new BufferedImage(bmp.bmWidth.intValue(), bmp.bmHeight.intValue() / 2, BufferedImage.TYPE_INT_ARGB);
- }
- }
- if (ret == null) {
- return ret;
- }
-
- if (info.hbmColor != null) {
- Gdi32.INSTANCE.DeleteObject(info.hbmColor);
- }
- if (info.hbmMask != null) {
- Gdi32.INSTANCE.DeleteObject(info.hbmMask);
- }
-
- drawIcon(ret, hIcon, User32.DI_NORMAL);
- BufferedImage mask = new BufferedImage(ret.getWidth(), ret.getHeight(), BufferedImage.TYPE_INT_RGB);
- drawIcon(mask, hIcon, User32.DI_MASK);
- applyMask(ret, mask);
-
- return ret;
- }
-
- public static BufferedImage getShellIcon(String path) {
- SHFILEINFO fi = new SHFILEINFO();
- BaseTSD.DWORD_PTR r = Shell32.INSTANCE.SHGetFileInfo(path, 0, fi, fi.size(), Shell32.SHGFI_ICON | Shell32.SHGFI_SMALLICON);
- if (r.intValue() == 0) {
- return null;
- }
- return iconToImage(fi.hIcon);
- }
-
- public static BufferedImage extractExeIcon(String fullExeFile, int index, boolean large) {
- PointerByReference iconsLargeRef = new PointerByReference();
- PointerByReference iconsSmallRef = new PointerByReference();
- int cnt = Shell32.INSTANCE.ExtractIconEx(fullExeFile, index, iconsLargeRef, iconsSmallRef, new WinDef.UINT(1)).intValue();
- if (cnt == 0) {
- return null;
- }
- Pointer iconsLarge = iconsLargeRef.getPointer();
- Pointer iconsSmall = iconsSmallRef.getPointer();
-
- WinDef.HICON icon;
- if (large) {
- icon = new WinDef.HICON(iconsLarge.getPointer(0));
- } else {
- icon = new WinDef.HICON(iconsSmall.getPointer(0));
- }
-
- BufferedImage ic = iconToImage(icon);
-
- User32.INSTANCE.DestroyIcon(icon);
- return ic;
- }
-
- public static List listProcesses() {
- if (!privAdjusted) {
- adjustPrivileges();
- }
- List ret = new ArrayList<>();
- WinNT.HANDLE hSnapShot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(new WinDef.DWORD(Kernel32.TH32CS_SNAPPROCESS), new WinDef.DWORD(0));
- PROCESSENTRY32 pe = new PROCESSENTRY32();
- if (Kernel32.INSTANCE.Process32First(hSnapShot, pe)) {
- do {
- int i;
- i = 0;
- for (; i < pe.szExeFile.length; i++) {
- if (pe.szExeFile[i] == 0) {
- break;
- }
- }
- String exeFile = new String(pe.szExeFile, 0, i);
- char[] outputnames = new char[1024];
- WinNT.HANDLE tempProcess = Kernel32.INSTANCE.OpenProcess(Kernel32.PROCESS_QUERY_INFORMATION, false, pe.th32ProcessID);
- if (tempProcess == null) {
- continue;
- }
-
- try {
- int rn = Psapi.INSTANCE.GetProcessImageFileNameW(tempProcess, outputnames, 1024);
- if (rn == 0) {
- Logger.getLogger(Win32ProcessTools.class.getName()).log(Level.SEVERE, "Can't get EXE path");
- }
- } catch (Exception | UnsatisfiedLinkError e) {
- }
-
- try {
- int rn = Kernel32.INSTANCE.GetProcessImageFileNameW(tempProcess, outputnames, 1024);
- if (rn == 0) {
- Logger.getLogger(Win32ProcessTools.class.getName()).log(Level.SEVERE, "Can't get EXE path");
- }
- } catch (Exception | UnsatisfiedLinkError e) {
- }
- i = 0;
- for (; i < outputnames.length; i++) {
- if (outputnames[i] == 0) {
- break;
- }
- }
- String fullExeFile = new String(outputnames, 0, i);
- fullExeFile = ntPathToWin32(fullExeFile);
- ret.add(new Win32Process(fullExeFile, exeFile, getShellIcon(fullExeFile), pe.th32ProcessID));
- } while (Kernel32.INSTANCE.Process32Next(hSnapShot, pe));
- }
- return ret;
- }
-
- private static boolean pageReadable(MEMORY_BASIC_INFORMATION mbi) {
- int iUnReadable = 0;
- iUnReadable |= (mbi.state.intValue() == Kernel32.MEM_FREE) ? 1 : 0;
- iUnReadable |= (mbi.state.intValue() == Kernel32.MEM_RESERVE) ? 1 : 0;
- iUnReadable |= (mbi.protect.intValue() & WinNT.PAGE_WRITECOPY);
- iUnReadable |= (mbi.protect.intValue() & WinNT.PAGE_EXECUTE);
- iUnReadable |= (mbi.protect.intValue() & WinNT.PAGE_GUARD);
- iUnReadable |= (mbi.protect.intValue() & WinNT.PAGE_NOACCESS);
- return iUnReadable == 0;
- }
-
- public static Map findBytesInProcessMemory(ProgressListener progListener, WinDef.DWORD dwProcessID, byte[][] findBytesAll) {
- int maxFindLen = 0;
- for (int i = 0; i < findBytesAll.length; i++) {
- if (findBytesAll[i].length > maxFindLen) {
- maxFindLen = findBytesAll[i].length;
- }
- }
- Map ret = new HashMap<>();
- WinNT.HANDLE hOtherProcess = Kernel32.INSTANCE.OpenProcess(Kernel32.PROCESS_VM_READ | Kernel32.PROCESS_VM_WRITE | Kernel32.PROCESS_QUERY_INFORMATION | Kernel32.PROCESS_VM_OPERATION /*for VirtualProtectEx*/, false, dwProcessID);
- List pages = getPageRanges(hOtherProcess);
- long totalMemLen = 0;
- int progress = 0;
- for (int pg = 0; pg < pages.size(); pg++) {
- totalMemLen += pages.get(pg).regionSize.longValue();
- }
-
- long actualPos = 0;
- byte[] prevBytes = new byte[0];
- List guardedPages = new ArrayList<>();
- for (int pg = 0; pg < pages.size(); pg++) {
- MEMORY_BASIC_INFORMATION mbi = pages.get(pg);
- if (pageReadable(mbi)) {
- int addr = (int) pointerToAddress(mbi.baseAddress);
- int maxsize = mbi.regionSize.intValue();
- int pos = 0;
- int bufSize = 1024;
- do {
- IntByReference bytesReadRef = new IntByReference();
- Memory buf = new Memory(bufSize);
- boolean ok = Kernel32.INSTANCE.ReadProcessMemory(hOtherProcess, addr + pos, buf, bufSize, bytesReadRef);
- if (!ok) {
- break;
- }
- if (bytesReadRef.getValue() == 0) {
- break;
- }
-
- byte[] data = buf.getByteArray(0, bytesReadRef.getValue());
-
- prevBytes = Arrays.copyOfRange(data, data.length - maxFindLen, data.length);
- byte[] dataPlusPrev = mergeArrays(prevBytes, data);
- loopi:
- for (int i = 0; i < dataPlusPrev.length - maxFindLen; i++) {
- loopk:
- for (int k = 0; k < findBytesAll.length; k++) {
- if (dataPlusPrev[i] == findBytesAll[k][0]) {
- for (int p = 1; p < findBytesAll[k].length; p++) {
- if (dataPlusPrev[i + p] != findBytesAll[k][p]) {
- continue loopk;
- }
- }
- long dataAddr = (long) (addr + pos - prevBytes.length + i);
- ret.put(dataAddr, new ProcessMemoryInputStream(pages, hOtherProcess, pg, pos - prevBytes.length + i));
- }
- }
-
- }
- pos += bytesReadRef.getValue();
- if (progListener != null) {
- int newprogress = Math.round((actualPos + pos) * 100 / totalMemLen);
- if (newprogress != progress) {
- progress = newprogress;
- progListener.progress(progress);
- }
- }
- if (pos + bufSize >= maxsize) {
- bufSize = maxsize - pos;
- }
- } while (bufSize > 0);
- } else {
- if (hasGuard(mbi)) {
- if (unsetGuard(hOtherProcess, mbi)) {
- guardedPages.add(pg);
- pg--;
- continue;
- }
- }
- }
- actualPos += mbi.regionSize.longValue();
- int newprogress = Math.round(actualPos * 100 / totalMemLen);
- if (newprogress != progress) {
- progress = newprogress;
- progListener.progress(progress);
- }
- }
-
- //Set PAGE_GUARD back again
- for (int pg : guardedPages) {
- setGuard(hOtherProcess, pages.get(pg));
- }
- return ret;
- }
-
- private static boolean hasGuard(MEMORY_BASIC_INFORMATION mbi) {
- return (mbi.protect.intValue() & WinNT.PAGE_GUARD) == WinNT.PAGE_GUARD;
- }
-
- private static boolean unsetGuard(HANDLE hOtherProcess, MEMORY_BASIC_INFORMATION mbi) {
- if (!hasGuard(mbi)) {
- return true;
- }
- int oldProt = mbi.protect.intValue();
- int newProt = oldProt - WinNT.PAGE_GUARD;
- IntByReference oldProtRef = new IntByReference();
- boolean ok = Kernel32.INSTANCE.VirtualProtectEx(hOtherProcess, new WinDef.LPVOID(pointerToAddress(mbi.baseAddress)), mbi.regionSize, newProt, oldProtRef);
- if (ok) {
- mbi.protect = new NativeLong(newProt);
- return true;
- }
- return false;
- }
-
- private static boolean setGuard(HANDLE hOtherProcess, MEMORY_BASIC_INFORMATION mbi) {
- if (hasGuard(mbi)) {
- return true;
- }
- int oldProt = mbi.protect.intValue();
- int newProt = oldProt | WinNT.PAGE_GUARD;
- IntByReference oldProtRef = new IntByReference();
- boolean ok = Kernel32.INSTANCE.VirtualProtectEx(hOtherProcess, new WinDef.LPVOID(pointerToAddress(mbi.baseAddress)), mbi.regionSize, newProt, oldProtRef);
- if (ok) {
- mbi.protect = new NativeLong(newProt);
- return true;
- }
- return false;
- }
- private static boolean privAdjusted = false;
-
- public static boolean adjustPrivileges() {
-
- WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1);
- WinNT.TOKEN_PRIVILEGES oldtp = new WinNT.TOKEN_PRIVILEGES(1);
- WinNT.LUID luid = new WinNT.LUID();
- WinNT.HANDLEByReference hTokenRef = new WinNT.HANDLEByReference();
- if (!Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), WinNT.TOKEN_ADJUST_PRIVILEGES | WinNT.TOKEN_QUERY, hTokenRef)) {
- return false;
- }
- WinNT.HANDLE hToken = hTokenRef.getValue();
- if (!Advapi32.INSTANCE.LookupPrivilegeValue(null, WinNT.SE_DEBUG_NAME, luid)) {
- Kernel32.INSTANCE.CloseHandle(hToken);
- return false;
- }
-
- tp.PrivilegeCount = new WinDef.DWORD(1);
- tp.Privileges = new WinNT.LUID_AND_ATTRIBUTES[1];
- tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(luid, new WinDef.DWORD(WinNT.SE_PRIVILEGE_ENABLED));
-
- IntByReference retSize = new IntByReference(0);
- if (!Advapi32.INSTANCE.AdjustTokenPrivileges(hToken, false, tp, tp.size(), oldtp, retSize)) {
- Kernel32.INSTANCE.CloseHandle(hToken);
- return false;
- }
- Kernel32.INSTANCE.CloseHandle(hToken);
- privAdjusted = true;
- return true;
- }
-
- private static class ProcessMemoryInputStream extends InputStream {
-
- private final List pages;
- private int currentPage = 0;
- private int pagePos = 0;
- private static final int BUFFER_SIZE = 1024;
- private byte[] buf;
- private int bufPos;
- private final HANDLE hOtherProcess;
-
- public ProcessMemoryInputStream(List pages, HANDLE hOtherProcess, int currentPage, int pagePos) {
- this.pages = pages;
- this.hOtherProcess = hOtherProcess;
- this.currentPage = currentPage;
- this.pagePos = pagePos;
- }
-
- private boolean readNext() throws IOException {
- MEMORY_BASIC_INFORMATION mbi = pages.get(currentPage);
- if (!pageReadable(mbi)) {
- if (hasGuard(mbi)) {
- if (unsetGuard(hOtherProcess, mbi)) {
- boolean ret = readNext();
- setGuard(hOtherProcess, mbi);
- return ret;
- }
- }
- if (currentPage + 1 < pages.size()) {
- pagePos = 0;
- currentPage++;
- return readNext();
- }
- return false;
- }
- int addr = (int) pointerToAddress(mbi.baseAddress);
- int maxsize = mbi.regionSize.intValue();
- IntByReference bytesReadRef = new IntByReference();
- Memory membuf = new Memory(BUFFER_SIZE);
- int bufSize = BUFFER_SIZE;
- if (pagePos + bufSize > maxsize) {
- bufSize = maxsize - pagePos;
- }
- if (bufSize == 0) {
- if (currentPage + 1 < pages.size()) {
- pagePos = 0;
- currentPage++;
- return readNext();
- }
- return false;
- }
- boolean ok = Kernel32.INSTANCE.ReadProcessMemory(hOtherProcess, addr + pagePos, membuf, bufSize, bytesReadRef);
- if (!ok) {
- throw new IOException("Cannot read memory");
- }
- if (bytesReadRef.getValue() == 0) {
- return readNext();
- }
- pagePos += bytesReadRef.getValue();
-
- buf = membuf.getByteArray(0, bytesReadRef.getValue());
- return true;
- }
-
- @Override
- public int read() throws IOException {
- if ((buf == null) || (bufPos >= buf.length)) {
- if (buf != null) {
- bufPos = 0;
- }
- if (!readNext()) {
- return -1;
- }
- }
-
- return buf[bufPos++] & 0xff;
- }
- }
-}
+/*
+ * Copyright (C) 2010-2014 JPEXS
+ *
+ * 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, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see .
+ */
+package com.jpexs.process.win32;
+
+import com.jpexs.helpers.ProgressListener;
+import com.jpexs.process.ProcessTools;
+import com.sun.jna.Memory;
+import com.sun.jna.NativeLong;
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.Advapi32;
+import com.sun.jna.platform.win32.BITMAP;
+import com.sun.jna.platform.win32.BaseTSD;
+import com.sun.jna.platform.win32.Gdi32;
+import com.sun.jna.platform.win32.ICONINFO;
+import com.sun.jna.platform.win32.Kernel32;
+import com.sun.jna.platform.win32.MEMORY_BASIC_INFORMATION;
+import com.sun.jna.platform.win32.PROCESSENTRY32;
+import com.sun.jna.platform.win32.Psapi;
+import com.sun.jna.platform.win32.SHFILEINFO;
+import com.sun.jna.platform.win32.Shell32;
+import com.sun.jna.platform.win32.User32;
+import com.sun.jna.platform.win32.WinBase;
+import com.sun.jna.platform.win32.WinDef;
+import com.sun.jna.platform.win32.WinNT;
+import com.sun.jna.platform.win32.WinNT.HANDLE;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.NativeLongByReference;
+import com.sun.jna.ptr.PointerByReference;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author JPEXS
+ */
+public class Win32ProcessTools extends ProcessTools {
+
+ private static long pointerToAddress(Pointer p) {
+ String s = p.toString();
+ s = s.replace("native@0x", "");
+ return Long.parseLong(s, 16);
+ }
+
+ public static List getPageRanges(WinNT.HANDLE hOtherProcess) {
+ List ret = new ArrayList<>();
+ MEMORY_BASIC_INFORMATION mbi;
+ WinBase.SYSTEM_INFO si = new WinBase.SYSTEM_INFO();
+ Kernel32.INSTANCE.GetSystemInfo(si);
+ Pointer lpMem = si.lpMinimumApplicationAddress;
+ while (pointerToAddress(lpMem) < pointerToAddress(si.lpMaximumApplicationAddress)) {
+ mbi = new MEMORY_BASIC_INFORMATION();
+ BaseTSD.SIZE_T t = Kernel32.INSTANCE.VirtualQueryEx(hOtherProcess, lpMem, mbi, new BaseTSD.SIZE_T(mbi.size()));
+ if (t.longValue() == 0) {
+ Logger.getLogger(Win32ProcessTools.class.getName()).log(Level.SEVERE, "Cannot get page ranges. Last error:" + Kernel32.INSTANCE.GetLastError());
+ break;
+ }
+ ret.add(mbi);
+ lpMem = new Pointer(pointerToAddress(mbi.baseAddress) + mbi.regionSize.longValue());
+ }
+ return ret;
+ }
+
+ public static void printMemInfo(MEMORY_BASIC_INFORMATION mbi) {
+ System.out.println("Region size:" + mbi.regionSize);
+ String stateStr = "";
+ if ((mbi.state.intValue() & Kernel32.MEM_COMMIT) == Kernel32.MEM_COMMIT) {
+ stateStr += " commit";
+ }
+ if ((mbi.state.intValue() & Kernel32.MEM_FREE) == Kernel32.MEM_FREE) {
+ stateStr += " free";
+ }
+ if ((mbi.state.intValue() & Kernel32.MEM_RESERVE) == Kernel32.MEM_RESERVE) {
+ stateStr += " reserve";
+ }
+ stateStr = stateStr.trim();
+
+ String typeStr = "";
+ if ((mbi.type.intValue() & Kernel32.MEM_IMAGE) == Kernel32.MEM_IMAGE) {
+ typeStr += " image";
+ }
+ if ((mbi.type.intValue() & Kernel32.MEM_MAPPED) == Kernel32.MEM_MAPPED) {
+ typeStr += " mapped";
+ }
+ if ((mbi.type.intValue() & Kernel32.MEM_PRIVATE) == Kernel32.MEM_PRIVATE) {
+ typeStr += " private";
+ }
+ typeStr = typeStr.trim();
+
+ String protStr = "";
+ if ((mbi.allocationProtect.intValue() & WinNT.PAGE_EXECUTE) == Kernel32.PAGE_EXECUTE) {
+ protStr += " execute";
+ }
+ if ((mbi.allocationProtect.intValue() & WinNT.PAGE_EXECUTE_READ) == Kernel32.PAGE_EXECUTE_READ) {
+ protStr += " execute_read";
+ }
+ if ((mbi.allocationProtect.intValue() & WinNT.PAGE_EXECUTE_READWRITE) == Kernel32.PAGE_EXECUTE_READWRITE) {
+ protStr += " execute_readwrite";
+ }
+ if ((mbi.allocationProtect.intValue() & WinNT.PAGE_READONLY) == Kernel32.PAGE_READONLY) {
+ protStr += " readonly";
+ }
+ if ((mbi.allocationProtect.intValue() & WinNT.PAGE_READWRITE) == Kernel32.PAGE_READWRITE) {
+ protStr += " readwrite";
+ }
+ if ((mbi.allocationProtect.intValue() & WinNT.PAGE_WRITECOPY) == Kernel32.PAGE_WRITECOPY) {
+ protStr += " writecopy";
+ }
+
+ protStr = protStr.trim();
+ System.out.println("State:" + stateStr);
+ System.out.println("Type:" + typeStr);
+ System.out.println("Protect:" + protStr);
+ System.out.println("baseAddress:" + mbi.baseAddress);
+ System.out.println("========================");
+ }
+
+ private static byte[] mergeArrays(byte[] one, byte[] two) {
+ byte[] combined = new byte[one.length + two.length];
+
+ System.arraycopy(one, 0, combined, 0, one.length);
+ System.arraycopy(two, 0, combined, one.length, two.length);
+ return combined;
+ }
+
+ public static Map getDriveMappings() {
+ Map ret = new HashMap<>();
+ for (char d = 'A'; d <= 'Z'; d++) {
+ char[] buf = new char[1024];
+ int len = Kernel32.INSTANCE.QueryDosDevice("" + d + ":", buf, buf.length).intValue();
+ String tar = new String(buf, 0, len);
+ tar = tar.trim();
+ if (!"".equals(tar)) {
+ ret.put(tar, d);
+ }
+ }
+ return ret;
+ }
+
+ public static String ntPathToWin32(String path) {
+ for (String dp : driveMappings.keySet()) {
+ if (path.startsWith(dp)) {
+ return driveMappings.get(dp) + ":" + path.substring(dp.length());
+ }
+ }
+ return path;
+ }
+ private static final Map driveMappings = getDriveMappings();
+
+ public static boolean drawIcon(BufferedImage ret, WinDef.HICON hIcon, int diFlags) {
+
+ WinDef.HDC hdcScreen = User32.INSTANCE.GetDC(null);
+ WinDef.HDC hdcMem = Gdi32.INSTANCE.CreateCompatibleDC(hdcScreen);
+
+ WinDef.HBITMAP bitmap = Gdi32.INSTANCE.CreateCompatibleBitmap(hdcScreen, ret.getWidth(), ret.getHeight());
+
+ WinNT.HANDLE hbmOld = Gdi32.INSTANCE.SelectObject(hdcMem, bitmap);
+
+ WinNT.HANDLE hBrush = Gdi32.INSTANCE.CreateSolidBrush(new WinDef.DWORD(0xffffff));
+ WinDef.RECT rect = new WinDef.RECT();
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = ret.getWidth();
+ rect.bottom = ret.getHeight();
+ User32.INSTANCE.FillRect(hdcMem, rect, hBrush);
+ Gdi32.INSTANCE.DeleteObject(hBrush);
+
+ boolean ok = User32.INSTANCE.DrawIconEx(hdcMem, 0, 0, hIcon, ret.getWidth(), ret.getHeight(), new WinDef.UINT(0), new WinDef.HBRUSH(Pointer.NULL), diFlags);
+
+ if (!ok) {
+ return false;
+ }
+
+ for (int x = 0; x < ret.getWidth(); x++) {
+ for (int y = 0; y < ret.getHeight(); y++) {
+ int rgb = Gdi32.INSTANCE.GetPixel(hdcMem, x, y).intValue();
+ int r = (rgb >> 16) & 0xff;
+ int g = (rgb >> 8) & 0xff;
+ int b = (rgb) & 0xff;
+ rgb = (b << 16) + (g << 8) + r;
+ ret.setRGB(x, y, rgb);
+ }
+ }
+
+ Gdi32.INSTANCE.SelectObject(hdcMem, hbmOld);
+ Gdi32.INSTANCE.DeleteObject(bitmap);
+ Gdi32.INSTANCE.DeleteDC(hdcMem);
+ User32.INSTANCE.ReleaseDC(null, hdcScreen);
+ return true;
+ }
+
+ private static void applyMask(BufferedImage image, BufferedImage mask) {
+ int width = image.getWidth();
+ int height = image.getHeight();
+ for (int x = 0; x < width; x++) {
+ for (int y = 0; y < height; y++) {
+ int masked = mask.getRGB(x, y);
+ int alpha = 255 - (masked & 0xff);
+ if (alpha != 0 && alpha != 255) {
+ System.out.println("a=" + alpha);
+ }
+ int rgb = image.getRGB(x, y);
+ int r = (rgb >> 16) & 0xff;
+ int g = (rgb >> 8) & 0xff;
+ int b = (rgb) & 0xff;
+ r = r * alpha / 255;
+ g = g * alpha / 255;
+ b = b * alpha / 255;
+
+ rgb = (r << 16) + (g << 8) + b;
+
+ rgb = (alpha << 24) | rgb;
+ image.setRGB(x, y, rgb);
+ }
+ }
+ }
+
+ public static BufferedImage iconToImage(WinDef.HICON hIcon) {
+ ICONINFO info = new ICONINFO();
+ boolean ok = User32.INSTANCE.GetIconInfo(hIcon, info);
+ if (!ok) {
+ return null;
+ }
+ BufferedImage ret = null;
+ BITMAP bmp = new BITMAP();
+ if (info.hbmColor != null) {
+ int nWrittenBytes = Gdi32.INSTANCE.GetObject(info.hbmColor, bmp.size(), bmp);
+ if (nWrittenBytes > 0) {
+ ret = new BufferedImage(bmp.bmWidth.intValue(), bmp.bmHeight.intValue(), BufferedImage.TYPE_INT_ARGB);
+ }
+ } else if (info.hbmMask != null) {
+ int nWrittenBytes = Gdi32.INSTANCE.GetObject(info.hbmMask, bmp.size(), bmp);
+ if (nWrittenBytes > 0) {
+ ret = new BufferedImage(bmp.bmWidth.intValue(), bmp.bmHeight.intValue() / 2, BufferedImage.TYPE_INT_ARGB);
+ }
+ }
+ if (ret == null) {
+ return ret;
+ }
+
+ if (info.hbmColor != null) {
+ Gdi32.INSTANCE.DeleteObject(info.hbmColor);
+ }
+ if (info.hbmMask != null) {
+ Gdi32.INSTANCE.DeleteObject(info.hbmMask);
+ }
+
+ drawIcon(ret, hIcon, User32.DI_NORMAL);
+ BufferedImage mask = new BufferedImage(ret.getWidth(), ret.getHeight(), BufferedImage.TYPE_INT_RGB);
+ drawIcon(mask, hIcon, User32.DI_MASK);
+ applyMask(ret, mask);
+
+ return ret;
+ }
+
+ public static BufferedImage getShellIcon(String path) {
+ SHFILEINFO fi = new SHFILEINFO();
+ BaseTSD.DWORD_PTR r = Shell32.INSTANCE.SHGetFileInfo(path, 0, fi, fi.size(), Shell32.SHGFI_ICON | Shell32.SHGFI_SMALLICON);
+ if (r.intValue() == 0) {
+ return null;
+ }
+ return iconToImage(fi.hIcon);
+ }
+
+ public static BufferedImage extractExeIcon(String fullExeFile, int index, boolean large) {
+ PointerByReference iconsLargeRef = new PointerByReference();
+ PointerByReference iconsSmallRef = new PointerByReference();
+ int cnt = Shell32.INSTANCE.ExtractIconEx(fullExeFile, index, iconsLargeRef, iconsSmallRef, new WinDef.UINT(1)).intValue();
+ if (cnt == 0) {
+ return null;
+ }
+ Pointer iconsLarge = iconsLargeRef.getPointer();
+ Pointer iconsSmall = iconsSmallRef.getPointer();
+
+ WinDef.HICON icon;
+ if (large) {
+ icon = new WinDef.HICON(iconsLarge.getPointer(0));
+ } else {
+ icon = new WinDef.HICON(iconsSmall.getPointer(0));
+ }
+
+ BufferedImage ic = iconToImage(icon);
+
+ User32.INSTANCE.DestroyIcon(icon);
+ return ic;
+ }
+
+ public static List listProcesses() {
+ if (!privAdjusted) {
+ adjustPrivileges();
+ }
+ List ret = new ArrayList<>();
+ WinNT.HANDLE hSnapShot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(new WinDef.DWORD(Kernel32.TH32CS_SNAPPROCESS), new WinDef.DWORD(0));
+ PROCESSENTRY32 pe = new PROCESSENTRY32();
+ if (Kernel32.INSTANCE.Process32First(hSnapShot, pe)) {
+ do {
+ int i;
+ i = 0;
+ for (; i < pe.szExeFile.length; i++) {
+ if (pe.szExeFile[i] == 0) {
+ break;
+ }
+ }
+ String exeFile = new String(pe.szExeFile, 0, i);
+ char[] outputnames = new char[1024];
+ WinNT.HANDLE tempProcess = Kernel32.INSTANCE.OpenProcess(Kernel32.PROCESS_QUERY_INFORMATION, false, pe.th32ProcessID);
+ if (tempProcess == null) {
+ continue;
+ }
+
+ try {
+ int rn = Psapi.INSTANCE.GetProcessImageFileNameW(tempProcess, outputnames, 1024);
+ if (rn == 0) {
+ Logger.getLogger(Win32ProcessTools.class.getName()).log(Level.SEVERE, "Can't get EXE path");
+ }
+ } catch (Exception | UnsatisfiedLinkError e) {
+ }
+
+ try {
+ int rn = Kernel32.INSTANCE.GetProcessImageFileNameW(tempProcess, outputnames, 1024);
+ if (rn == 0) {
+ Logger.getLogger(Win32ProcessTools.class.getName()).log(Level.SEVERE, "Can't get EXE path");
+ }
+ } catch (Exception | UnsatisfiedLinkError e) {
+ }
+ i = 0;
+ for (; i < outputnames.length; i++) {
+ if (outputnames[i] == 0) {
+ break;
+ }
+ }
+ String fullExeFile = new String(outputnames, 0, i);
+ fullExeFile = ntPathToWin32(fullExeFile);
+ ret.add(new Win32Process(fullExeFile, exeFile, getShellIcon(fullExeFile), pe.th32ProcessID));
+ } while (Kernel32.INSTANCE.Process32Next(hSnapShot, pe));
+ }
+ return ret;
+ }
+
+ private static boolean pageReadable(MEMORY_BASIC_INFORMATION mbi) {
+ int iUnReadable = 0;
+ iUnReadable |= (mbi.state.intValue() == Kernel32.MEM_FREE) ? 1 : 0;
+ iUnReadable |= (mbi.state.intValue() == Kernel32.MEM_RESERVE) ? 1 : 0;
+ iUnReadable |= (mbi.protect.intValue() & WinNT.PAGE_WRITECOPY);
+ iUnReadable |= (mbi.protect.intValue() & WinNT.PAGE_EXECUTE);
+ iUnReadable |= (mbi.protect.intValue() & WinNT.PAGE_GUARD);
+ iUnReadable |= (mbi.protect.intValue() & WinNT.PAGE_NOACCESS);
+ return iUnReadable == 0;
+ }
+
+ public static Map findBytesInProcessMemory(ProgressListener progListener, WinDef.DWORD dwProcessID, byte[][] findBytesAll) {
+ int maxFindLen = 0;
+ for (int i = 0; i < findBytesAll.length; i++) {
+ if (findBytesAll[i].length > maxFindLen) {
+ maxFindLen = findBytesAll[i].length;
+ }
+ }
+ Map ret = new HashMap<>();
+ WinNT.HANDLE hOtherProcess = Kernel32.INSTANCE.OpenProcess(Kernel32.PROCESS_VM_READ | Kernel32.PROCESS_VM_WRITE | Kernel32.PROCESS_QUERY_INFORMATION | Kernel32.PROCESS_VM_OPERATION /*for VirtualProtectEx*/, false, dwProcessID);
+ List pages = getPageRanges(hOtherProcess);
+ long totalMemLen = 0;
+ int progress = 0;
+ for (int pg = 0; pg < pages.size(); pg++) {
+ totalMemLen += pages.get(pg).regionSize.longValue();
+ }
+
+ long actualPos = 0;
+ byte[] prevBytes = new byte[0];
+ List guardedPages = new ArrayList<>();
+ for (int pg = 0; pg < pages.size(); pg++) {
+ MEMORY_BASIC_INFORMATION mbi = pages.get(pg);
+ if (pageReadable(mbi)) {
+ long addr = pointerToAddress(mbi.baseAddress);
+ int maxsize = mbi.regionSize.intValue();
+ long pos = 0;
+ long bufSize = 1024*512;
+ do {
+ NativeLongByReference bytesReadRef = new NativeLongByReference();
+ Memory buf = new Memory(bufSize);
+ boolean ok = Kernel32.INSTANCE.ReadProcessMemory(hOtherProcess, new Pointer(addr + pos), buf, new NativeLong(bufSize), bytesReadRef);
+ if (!ok) {
+ break;
+ }
+ if (bytesReadRef.getValue().longValue() == 0) {
+ break;
+ }
+
+ byte[] data = buf.getByteArray(0, bytesReadRef.getValue().intValue());
+
+ prevBytes = Arrays.copyOfRange(data, data.length - maxFindLen, data.length);
+ byte[] dataPlusPrev = mergeArrays(prevBytes, data);
+ loopi:
+ for (int i = 0; i < dataPlusPrev.length - maxFindLen; i++) {
+ loopk:
+ for (int k = 0; k < findBytesAll.length; k++) {
+ if (dataPlusPrev[i] == findBytesAll[k][0]) {
+ for (int p = 1; p < findBytesAll[k].length; p++) {
+ if (dataPlusPrev[i + p] != findBytesAll[k][p]) {
+ continue loopk;
+ }
+ }
+ long dataAddr = (long) (addr + pos - prevBytes.length + i);
+ ret.put(dataAddr, new ProcessMemoryInputStream(pages, hOtherProcess, pg, pos - prevBytes.length + i));
+ }
+ }
+
+ }
+ pos += bytesReadRef.getValue().longValue();
+ if (progListener != null) {
+ int newprogress = Math.round((actualPos + pos) * 100 / totalMemLen);
+ if (newprogress != progress) {
+ progress = newprogress;
+ progListener.progress(progress);
+ }
+ }
+ if (pos + bufSize >= maxsize) {
+ bufSize = maxsize - pos;
+ }
+ } while (bufSize > 0);
+ } else {
+ if (hasGuard(mbi)) {
+ if (unsetGuard(hOtherProcess, mbi)) {
+ guardedPages.add(pg);
+ pg--;
+ continue;
+ }
+ }
+ }
+ actualPos += mbi.regionSize.longValue();
+ int newprogress = Math.round(actualPos * 100 / totalMemLen);
+ if (newprogress != progress) {
+ progress = newprogress;
+ progListener.progress(progress);
+ }
+ }
+
+ //Set PAGE_GUARD back again
+ for (int pg : guardedPages) {
+ setGuard(hOtherProcess, pages.get(pg));
+ }
+ return ret;
+ }
+
+ private static boolean hasGuard(MEMORY_BASIC_INFORMATION mbi) {
+ return (mbi.protect.intValue() & WinNT.PAGE_GUARD) == WinNT.PAGE_GUARD;
+ }
+
+ private static boolean unsetGuard(HANDLE hOtherProcess, MEMORY_BASIC_INFORMATION mbi) {
+ if (!hasGuard(mbi)) {
+ return true;
+ }
+ int oldProt = mbi.protect.intValue();
+ int newProt = oldProt - WinNT.PAGE_GUARD;
+ IntByReference oldProtRef = new IntByReference();
+ boolean ok = Kernel32.INSTANCE.VirtualProtectEx(hOtherProcess, new WinDef.LPVOID(pointerToAddress(mbi.baseAddress)), mbi.regionSize, newProt, oldProtRef);
+ if (ok) {
+ mbi.protect = new NativeLong(newProt);
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean setGuard(HANDLE hOtherProcess, MEMORY_BASIC_INFORMATION mbi) {
+ if (hasGuard(mbi)) {
+ return true;
+ }
+ int oldProt = mbi.protect.intValue();
+ int newProt = oldProt | WinNT.PAGE_GUARD;
+ IntByReference oldProtRef = new IntByReference();
+ boolean ok = Kernel32.INSTANCE.VirtualProtectEx(hOtherProcess, new WinDef.LPVOID(pointerToAddress(mbi.baseAddress)), mbi.regionSize, newProt, oldProtRef);
+ if (ok) {
+ mbi.protect = new NativeLong(newProt);
+ return true;
+ }
+ return false;
+ }
+ private static boolean privAdjusted = false;
+
+ public static boolean adjustPrivileges() {
+
+ WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1);
+ WinNT.TOKEN_PRIVILEGES oldtp = new WinNT.TOKEN_PRIVILEGES(1);
+ WinNT.LUID luid = new WinNT.LUID();
+ WinNT.HANDLEByReference hTokenRef = new WinNT.HANDLEByReference();
+ if (!Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), WinNT.TOKEN_ADJUST_PRIVILEGES | WinNT.TOKEN_QUERY, hTokenRef)) {
+ return false;
+ }
+ WinNT.HANDLE hToken = hTokenRef.getValue();
+ if (!Advapi32.INSTANCE.LookupPrivilegeValue(null, WinNT.SE_DEBUG_NAME, luid)) {
+ Kernel32.INSTANCE.CloseHandle(hToken);
+ return false;
+ }
+
+ tp.PrivilegeCount = new WinDef.DWORD(1);
+ tp.Privileges = new WinNT.LUID_AND_ATTRIBUTES[1];
+ tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(luid, new WinDef.DWORD(WinNT.SE_PRIVILEGE_ENABLED));
+
+ IntByReference retSize = new IntByReference(0);
+ if (!Advapi32.INSTANCE.AdjustTokenPrivileges(hToken, false, tp, tp.size(), oldtp, retSize)) {
+ Kernel32.INSTANCE.CloseHandle(hToken);
+ return false;
+ }
+ Kernel32.INSTANCE.CloseHandle(hToken);
+ privAdjusted = true;
+ return true;
+ }
+
+ private static class ProcessMemoryInputStream extends InputStream {
+
+ private final List pages;
+ private int currentPage = 0;
+ private long pagePos = 0;
+ private static final int BUFFER_SIZE = 1024*512;
+ private byte[] buf;
+ private int bufPos;
+ private final HANDLE hOtherProcess;
+
+ public ProcessMemoryInputStream(List pages, HANDLE hOtherProcess, int currentPage, long pagePos) {
+ this.pages = pages;
+ this.hOtherProcess = hOtherProcess;
+ this.currentPage = currentPage;
+ this.pagePos = pagePos;
+ }
+
+ private boolean readNext() throws IOException {
+ MEMORY_BASIC_INFORMATION mbi = pages.get(currentPage);
+ if (!pageReadable(mbi)) {
+ if (hasGuard(mbi)) {
+ if (unsetGuard(hOtherProcess, mbi)) {
+ boolean ret = readNext();
+ setGuard(hOtherProcess, mbi);
+ return ret;
+ }
+ }
+ if (currentPage + 1 < pages.size()) {
+ pagePos = 0;
+ currentPage++;
+ return readNext();
+ }
+ return false;
+ }
+ long addr = pointerToAddress(mbi.baseAddress);
+ int maxsize = mbi.regionSize.intValue();
+ NativeLongByReference bytesReadRef = new NativeLongByReference();
+ Memory membuf = new Memory(BUFFER_SIZE);
+ NativeLong bufSize = new NativeLong(BUFFER_SIZE);
+ if (pagePos + bufSize.longValue() > maxsize) {
+ bufSize.setValue(maxsize - pagePos);
+ }
+ if (bufSize.longValue() == 0) {
+ if (currentPage + 1 < pages.size()) {
+ pagePos = 0;
+ currentPage++;
+ return readNext();
+ }
+ return false;
+ }
+ boolean ok = Kernel32.INSTANCE.ReadProcessMemory(hOtherProcess, new Pointer(addr + pagePos), membuf, bufSize, bytesReadRef);
+ if (!ok) {
+ throw new IOException("Cannot read memory");
+ }
+ if (bytesReadRef.getValue().longValue() == 0) {
+ return readNext();
+ }
+ pagePos += bytesReadRef.getValue().longValue();
+
+ buf = membuf.getByteArray(0, bytesReadRef.getValue().intValue());
+ return true;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if ((buf == null) || (bufPos >= buf.length)) {
+ if (buf != null) {
+ bufPos = 0;
+ }
+ if (!readNext()) {
+ return -1;
+ }
+ }
+
+ return buf[bufPos++] & 0xff;
+ }
+ }
+}
diff --git a/src/com/sun/jna/platform/win32/Kernel32.java b/src/com/sun/jna/platform/win32/Kernel32.java
index 8fe3131c0..2730c4b2e 100644
--- a/src/com/sun/jna/platform/win32/Kernel32.java
+++ b/src/com/sun/jna/platform/win32/Kernel32.java
@@ -1,300 +1,302 @@
-/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
- *
- * 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.sun.jna.platform.win32;
-
-import com.sun.jna.Native;
-import com.sun.jna.Pointer;
-import com.sun.jna.ptr.IntByReference;
-import com.sun.jna.win32.W32APIOptions;
-
-// TODO: Auto-generated Javadoc
-/**
- * Interface definitions for kernel32.dll. Includes additional
- * alternate mappings from {@link WinNT} which make use of NIO buffers.
- */
-public interface Kernel32 extends WinNT {
-
- /**
- * The instance.
- */
- Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32",
- Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
-
- /**
- * The CloseHandle function closes an open object handle.
- *
- * @param hObject Handle to an open object. This parameter can be a pseudo
- * handle or INVALID_HANDLE_VALUE.
- * @return If the function succeeds, the return value is nonzero. If the
- * function fails, the return value is zero. To get extended error
- * information, call GetLastError.
- */
- boolean CloseHandle(HANDLE hObject);
-
- /**
- * Terminates the specified process and all of its threads.
- *
- * @param hProcess A handle to the process to be terminated.
- * @param uExitCode The exit code to be used by the process and threads
- * terminated as a result of this call.
- * @return If the function succeeds, the return value is nonzero.
- *
- * If the function fails, the return value is zero. To get extended error
- * information, call GetLastError.
- */
- boolean TerminateProcess(HANDLE hProcess, int uExitCode);
-
- /**
- * Writes data to the specified file or input/output (I/O) device.
- *
- * @param hFile A handle to the file or I/O device (for example, a file,
- * file stream, physical disk, volume, console buffer, tape drive, socket,
- * communications resource, mailslot, or pipe).
- * @param lpBuffer A pointer to the buffer containing the data to be written
- * to the file or device.
- * @param nNumberOfBytesToWrite The number of bytes to be written to the
- * file or device.
- * @param lpNumberOfBytesWritten A pointer to the variable that receives the
- * number of bytes written when using a synchronous hFile parameter.
- * @param lpOverlapped A pointer to an OVERLAPPED structure is required if
- * the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this
- * parameter can be NULL.
- * @return If the function succeeds, the return value is nonzero (TRUE). If
- * the function fails, or is completing asynchronously, the return value is
- * zero (FALSE). To get extended error information, call the GetLastError
- * function.
- */
- boolean WriteFile(HANDLE hFile, byte[] lpBuffer, int nNumberOfBytesToWrite,
- IntByReference lpNumberOfBytesWritten,
- WinBase.OVERLAPPED lpOverlapped);
-
- boolean ReadFile(HANDLE hFile, byte[] lpBuffer, int nNumberOfBytesToRead, IntByReference lpNumberOfBytesRead, WinBase.OVERLAPPED lpOverlapped);
- //
- // Define the NamedPipe definitions
- //
- //
- // Define the dwOpenMode values for CreateNamedPipe
- //
- public static final int PIPE_ACCESS_INBOUND = 0x00000001;
- public static final int PIPE_ACCESS_OUTBOUND = 0x00000002;
- public static final int PIPE_ACCESS_DUPLEX = 0x00000003;
- //
- // Define the Named Pipe End flags for GetNamedPipeInfo
- //
- public static final int PIPE_CLIENT_END = 0x00000000;
- public static final int PIPE_SERVER_END = 0x00000001;
- //
- // Define the dwPipeMode values for CreateNamedPipe
- //
- public static final int PIPE_WAIT = 0x00000000;
- public static final int PIPE_NOWAIT = 0x00000001;
- public static final int PIPE_READMODE_BYTE = 0x00000000;
- public static final int PIPE_READMODE_MESSAGE = 0x00000002;
- public static final int PIPE_TYPE_BYTE = 0x00000000;
- public static final int PIPE_TYPE_MESSAGE = 0x00000004;
- public static final int PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000;
- public static final int PIPE_REJECT_REMOTE_CLIENTS = 0x00000008;
- //
- // Define the well known values for CreateNamedPipe nMaxInstances
- //
- public static final int PIPE_UNLIMITED_INSTANCES = 255;
- //
- // Define the values for process priority
- //
- public static final int ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000;
- public static final int BELOW_NORMAL_PRIORITY_CLASS = 0x00004000;
- public static final int HIGH_PRIORITY_CLASS = 0x00000080;
- public static final int IDLE_PRIORITY_CLASS = 0x00000040;
- public static final int NORMAL_PRIORITY_CLASS = 0x00000020;
- public static final int PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000;
- public static final int PROCESS_MODE_BACKGROUND_END = 0x00200000;
- public static final int REALTIME_PRIORITY_CLASS = 0x00000100;
-
-// __out
-// HANDLE
-// WINAPI
-// CreateNamedPipe(
-// __in LPCWSTR lpName,
-// __in DWORD dwOpenMode,
-// __in DWORD dwPipeMode,
-// __in DWORD nMaxInstances,
-// __in DWORD nOutBufferSize,
-// __in DWORD nInBufferSize,
-// __in DWORD nDefaultTimeOut,
-// __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes
-// );
- HANDLE CreateNamedPipe(String lpName, int dwOpenMode, int dwPipeMode, int nMaxInstances, int nOutBufferSize, int nInBufferSize, int nDefaultTimeOut,
- WinBase.SECURITY_ATTRIBUTES lpSecurityAttributes);
-
- // WINBASEAPI
-// BOOL
-// WINAPI
-// ConnectNamedPipe(
-// __in HANDLE hNamedPipe,
-// __inout_opt LPOVERLAPPED lpOverlapped
-// );
- boolean ConnectNamedPipe(HANDLE hNamedPipe, WinBase.OVERLAPPED lpOverlapped);
-
-// WINBASEAPI
-// BOOL
-// WINAPI
-// DisconnectNamedPipe(
-// __in HANDLE hNamedPipe
-// );
- boolean DisconnectNamedPipe(HANDLE hNamedPipe);
-
- /**
- * Waits until the specified object is in the signaled state or the time-out
- * interval elapses. To enter an alertable wait state, use the
- * WaitForSingleObjectEx function. To wait for multiple objects, use the
- * WaitForMultipleObjects.
- *
- * @param hHandle A handle to the object. For a list of the object types
- * whose handles can be specified, see the following Remarks section. If
- * this handle is closed while the wait is still pending, the function's
- * behavior is undefined. The handle must have the SYNCHRONIZE access right.
- * For more information, see Standard Access Rights.
- * @param dwMilliseconds The time-out interval, in milliseconds. If a
- * nonzero value is specified, the function waits until the object is
- * signaled or the interval elapses. If dwMilliseconds is zero, the function
- * does not enter a wait state if the object is not signaled; it always
- * returns immediately. If dwMilliseconds is INFINITE, the function will
- * return only when the object is signaled.
- * @return If the function succeeds, the return value indicates the event
- * that caused the function to return.
- */
- int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds);
-
- /**
- * This function returns a pseudohandle for the current process.
- *
- * @return The return value is a pseudohandle to the current process.
- */
- HANDLE GetCurrentProcess();
-
- int SetProcessAffinityMask(HANDLE hProcess, int mask);
-
- int SetPriorityClass(HANDLE hProcess, int dwPriorityClass);
-
- /**
- * This function returns a handle to an existing process object.
- *
- * @param fdwAccess Not supported; set to zero.
- * @param fInherit Not supported; set to FALSE.
- * @param IDProcess Specifies the process identifier of the process to open.
- * @return An open handle to the specified process indicates success. NULL
- * indicates failure. To get extended error information, call GetLastError.
- */
- HANDLE OpenProcess(int fdwAccess, boolean fInherit, DWORD IDProcess);
-
- /**
- * The GetSystemInfo function returns information about the current system.
- *
- * @param lpSystemInfo Pointer to a SYSTEM_INFO structure that receives the
- * information.
- */
- void GetSystemInfo(SYSTEM_INFO lpSystemInfo);
- public static final int PROCESS_VM_READ = 0x0010;
- public static final int PROCESS_VM_WRITE = 0x0020;
- public static final int PROCESS_QUERY_INFORMATION = 0x0400;
- public static final int PROCESS_VM_OPERATION = 0x0008;
-
- SIZE_T VirtualQueryEx(HANDLE hProcess, Pointer lpAddress, MEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
-
- /**
- * The GetLastError function retrieves the calling thread's last-error code
- * value. The last-error code is maintained on a per-thread basis. Multiple
- * threads do not overwrite each other's last-error code.
- *
- * @return The return value is the calling thread's last-error code value.
- */
- int GetLastError();
- public static int MEM_COMMIT = 0x1000;
- public static int MEM_FREE = 0x10000;
- public static int MEM_RESERVE = 0x2000;
- public static int MEM_IMAGE = 0x1000000;
- public static int MEM_MAPPED = 0x40000;
- public static int MEM_PRIVATE = 0x20000;
-
- boolean ReadProcessMemory(HANDLE hProcess, int inBaseAddress, Pointer outputBuffer, int nSize, IntByReference outNumberOfBytesRead);
-
- /**
- * 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.
- */
- HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, 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.
- */
- boolean Process32First(HANDLE hSnapshot, PROCESSENTRY32 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.
- */
- boolean Process32Next(HANDLE hSnapshot, PROCESSENTRY32 lppe);
- public static int TH32CS_SNAPPROCESS = 0x00000002;
-
- //Needed for some Windows 7 Versions
- //boolean EnumProcesses(int[] ProcessIDsOut, int size, int[] BytesReturned);
- int GetProcessImageFileNameW(HANDLE Process, char[] outputname, int lenght);
-
- DWORD QueryDosDevice(String lpDeviceName, char[] lpTargetPath, int lenght);
-
- boolean VirtualProtectEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, int flNewProtect, IntByReference lpflOldProtect);
-}
+/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
+ *
+ * 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.sun.jna.platform.win32;
+
+import com.sun.jna.Native;
+import com.sun.jna.NativeLong;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.NativeLongByReference;
+import com.sun.jna.win32.W32APIOptions;
+
+// TODO: Auto-generated Javadoc
+/**
+ * Interface definitions for kernel32.dll. Includes additional
+ * alternate mappings from {@link WinNT} which make use of NIO buffers.
+ */
+public interface Kernel32 extends WinNT {
+
+ /**
+ * The instance.
+ */
+ Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32",
+ Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
+
+ /**
+ * The CloseHandle function closes an open object handle.
+ *
+ * @param hObject Handle to an open object. This parameter can be a pseudo
+ * handle or INVALID_HANDLE_VALUE.
+ * @return If the function succeeds, the return value is nonzero. If the
+ * function fails, the return value is zero. To get extended error
+ * information, call GetLastError.
+ */
+ boolean CloseHandle(HANDLE hObject);
+
+ /**
+ * Terminates the specified process and all of its threads.
+ *
+ * @param hProcess A handle to the process to be terminated.
+ * @param uExitCode The exit code to be used by the process and threads
+ * terminated as a result of this call.
+ * @return If the function succeeds, the return value is nonzero.
+ *
+ * If the function fails, the return value is zero. To get extended error
+ * information, call GetLastError.
+ */
+ boolean TerminateProcess(HANDLE hProcess, int uExitCode);
+
+ /**
+ * Writes data to the specified file or input/output (I/O) device.
+ *
+ * @param hFile A handle to the file or I/O device (for example, a file,
+ * file stream, physical disk, volume, console buffer, tape drive, socket,
+ * communications resource, mailslot, or pipe).
+ * @param lpBuffer A pointer to the buffer containing the data to be written
+ * to the file or device.
+ * @param nNumberOfBytesToWrite The number of bytes to be written to the
+ * file or device.
+ * @param lpNumberOfBytesWritten A pointer to the variable that receives the
+ * number of bytes written when using a synchronous hFile parameter.
+ * @param lpOverlapped A pointer to an OVERLAPPED structure is required if
+ * the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this
+ * parameter can be NULL.
+ * @return If the function succeeds, the return value is nonzero (TRUE). If
+ * the function fails, or is completing asynchronously, the return value is
+ * zero (FALSE). To get extended error information, call the GetLastError
+ * function.
+ */
+ boolean WriteFile(HANDLE hFile, byte[] lpBuffer, int nNumberOfBytesToWrite,
+ IntByReference lpNumberOfBytesWritten,
+ WinBase.OVERLAPPED lpOverlapped);
+
+ boolean ReadFile(HANDLE hFile, byte[] lpBuffer, int nNumberOfBytesToRead, IntByReference lpNumberOfBytesRead, WinBase.OVERLAPPED lpOverlapped);
+ //
+ // Define the NamedPipe definitions
+ //
+ //
+ // Define the dwOpenMode values for CreateNamedPipe
+ //
+ public static final int PIPE_ACCESS_INBOUND = 0x00000001;
+ public static final int PIPE_ACCESS_OUTBOUND = 0x00000002;
+ public static final int PIPE_ACCESS_DUPLEX = 0x00000003;
+ //
+ // Define the Named Pipe End flags for GetNamedPipeInfo
+ //
+ public static final int PIPE_CLIENT_END = 0x00000000;
+ public static final int PIPE_SERVER_END = 0x00000001;
+ //
+ // Define the dwPipeMode values for CreateNamedPipe
+ //
+ public static final int PIPE_WAIT = 0x00000000;
+ public static final int PIPE_NOWAIT = 0x00000001;
+ public static final int PIPE_READMODE_BYTE = 0x00000000;
+ public static final int PIPE_READMODE_MESSAGE = 0x00000002;
+ public static final int PIPE_TYPE_BYTE = 0x00000000;
+ public static final int PIPE_TYPE_MESSAGE = 0x00000004;
+ public static final int PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000;
+ public static final int PIPE_REJECT_REMOTE_CLIENTS = 0x00000008;
+ //
+ // Define the well known values for CreateNamedPipe nMaxInstances
+ //
+ public static final int PIPE_UNLIMITED_INSTANCES = 255;
+ //
+ // Define the values for process priority
+ //
+ public static final int ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000;
+ public static final int BELOW_NORMAL_PRIORITY_CLASS = 0x00004000;
+ public static final int HIGH_PRIORITY_CLASS = 0x00000080;
+ public static final int IDLE_PRIORITY_CLASS = 0x00000040;
+ public static final int NORMAL_PRIORITY_CLASS = 0x00000020;
+ public static final int PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000;
+ public static final int PROCESS_MODE_BACKGROUND_END = 0x00200000;
+ public static final int REALTIME_PRIORITY_CLASS = 0x00000100;
+
+// __out
+// HANDLE
+// WINAPI
+// CreateNamedPipe(
+// __in LPCWSTR lpName,
+// __in DWORD dwOpenMode,
+// __in DWORD dwPipeMode,
+// __in DWORD nMaxInstances,
+// __in DWORD nOutBufferSize,
+// __in DWORD nInBufferSize,
+// __in DWORD nDefaultTimeOut,
+// __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes
+// );
+ HANDLE CreateNamedPipe(String lpName, int dwOpenMode, int dwPipeMode, int nMaxInstances, int nOutBufferSize, int nInBufferSize, int nDefaultTimeOut,
+ WinBase.SECURITY_ATTRIBUTES lpSecurityAttributes);
+
+ // WINBASEAPI
+// BOOL
+// WINAPI
+// ConnectNamedPipe(
+// __in HANDLE hNamedPipe,
+// __inout_opt LPOVERLAPPED lpOverlapped
+// );
+ boolean ConnectNamedPipe(HANDLE hNamedPipe, WinBase.OVERLAPPED lpOverlapped);
+
+// WINBASEAPI
+// BOOL
+// WINAPI
+// DisconnectNamedPipe(
+// __in HANDLE hNamedPipe
+// );
+ boolean DisconnectNamedPipe(HANDLE hNamedPipe);
+
+ /**
+ * Waits until the specified object is in the signaled state or the time-out
+ * interval elapses. To enter an alertable wait state, use the
+ * WaitForSingleObjectEx function. To wait for multiple objects, use the
+ * WaitForMultipleObjects.
+ *
+ * @param hHandle A handle to the object. For a list of the object types
+ * whose handles can be specified, see the following Remarks section. If
+ * this handle is closed while the wait is still pending, the function's
+ * behavior is undefined. The handle must have the SYNCHRONIZE access right.
+ * For more information, see Standard Access Rights.
+ * @param dwMilliseconds The time-out interval, in milliseconds. If a
+ * nonzero value is specified, the function waits until the object is
+ * signaled or the interval elapses. If dwMilliseconds is zero, the function
+ * does not enter a wait state if the object is not signaled; it always
+ * returns immediately. If dwMilliseconds is INFINITE, the function will
+ * return only when the object is signaled.
+ * @return If the function succeeds, the return value indicates the event
+ * that caused the function to return.
+ */
+ int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds);
+
+ /**
+ * This function returns a pseudohandle for the current process.
+ *
+ * @return The return value is a pseudohandle to the current process.
+ */
+ HANDLE GetCurrentProcess();
+
+ int SetProcessAffinityMask(HANDLE hProcess, int mask);
+
+ int SetPriorityClass(HANDLE hProcess, int dwPriorityClass);
+
+ /**
+ * This function returns a handle to an existing process object.
+ *
+ * @param fdwAccess Not supported; set to zero.
+ * @param fInherit Not supported; set to FALSE.
+ * @param IDProcess Specifies the process identifier of the process to open.
+ * @return An open handle to the specified process indicates success. NULL
+ * indicates failure. To get extended error information, call GetLastError.
+ */
+ HANDLE OpenProcess(int fdwAccess, boolean fInherit, DWORD IDProcess);
+
+ /**
+ * The GetSystemInfo function returns information about the current system.
+ *
+ * @param lpSystemInfo Pointer to a SYSTEM_INFO structure that receives the
+ * information.
+ */
+ void GetSystemInfo(SYSTEM_INFO lpSystemInfo);
+ public static final int PROCESS_VM_READ = 0x0010;
+ public static final int PROCESS_VM_WRITE = 0x0020;
+ public static final int PROCESS_QUERY_INFORMATION = 0x0400;
+ public static final int PROCESS_VM_OPERATION = 0x0008;
+
+ SIZE_T VirtualQueryEx(HANDLE hProcess, Pointer lpAddress, MEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
+
+ /**
+ * The GetLastError function retrieves the calling thread's last-error code
+ * value. The last-error code is maintained on a per-thread basis. Multiple
+ * threads do not overwrite each other's last-error code.
+ *
+ * @return The return value is the calling thread's last-error code value.
+ */
+ int GetLastError();
+ public static int MEM_COMMIT = 0x1000;
+ public static int MEM_FREE = 0x10000;
+ public static int MEM_RESERVE = 0x2000;
+ public static int MEM_IMAGE = 0x1000000;
+ public static int MEM_MAPPED = 0x40000;
+ public static int MEM_PRIVATE = 0x20000;
+
+ boolean ReadProcessMemory(HANDLE hProcess, Pointer inBaseAddress, Pointer outputBuffer, NativeLong nSize, NativeLongByReference outNumberOfBytesRead);
+
+ /**
+ * 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.
+ */
+ HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, 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.
+ */
+ boolean Process32First(HANDLE hSnapshot, PROCESSENTRY32 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.
+ */
+ boolean Process32Next(HANDLE hSnapshot, PROCESSENTRY32 lppe);
+ public static int TH32CS_SNAPPROCESS = 0x00000002;
+
+ //Needed for some Windows 7 Versions
+ //boolean EnumProcesses(int[] ProcessIDsOut, int size, int[] BytesReturned);
+ int GetProcessImageFileNameW(HANDLE Process, char[] outputname, int lenght);
+
+ DWORD QueryDosDevice(String lpDeviceName, char[] lpTargetPath, int lenght);
+
+ boolean VirtualProtectEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, int flNewProtect, IntByReference lpflOldProtect);
+}