From ebfdd12f600f078312c3c76ecd9782ef0ef50732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Thu, 28 Aug 2014 22:35:31 +0200 Subject: [PATCH] Issue #656 Search in memory - 64 bit processes fix --- .../src/com/jpexs/helpers/Helper.java | 2 +- .../process/win32/Win32ProcessTools.java | 1211 +++++++++-------- src/com/sun/jna/platform/win32/Kernel32.java | 602 ++++---- 3 files changed, 909 insertions(+), 906 deletions(-) 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); +}