/* 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. * <p/> * 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.examples.win32; import java.nio.Buffer; import java.util.Date; import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.ptr.ByReference; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; /** Definition (incomplete) of <code>kernel32.dll</code>. */ public interface Kernel32 extends W32API { Kernel32 INSTANCE = (Kernel32) Native.loadLibrary( "kernel32", Kernel32.class, DEFAULT_OPTIONS); //$NON-NLS-1$ class SYSTEMTIME extends Structure { public short wYear; public short wMonth; public short wDayOfWeek; public short wDay; public short wHour; public short wMinute; public short wSecond; public short wMilliseconds; } Pointer LocalFree(Pointer hLocal); Pointer GlobalFree(Pointer hGlobal); HMODULE GetModuleHandle(String name); void GetSystemTime(SYSTEMTIME result); int GetCurrentThreadId(); HANDLE GetCurrentThread(); int GetCurrentProcessId(); HANDLE GetCurrentProcess(); int GetProcessId(HANDLE process); int GetProcessVersion(int processId); int GetLastError(); void SetLastError(int dwErrCode); int GetDriveType(String rootPathName); int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x0100; int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000; int FORMAT_MESSAGE_IGNORE_INSERTS = 0x200; int FormatMessage(int dwFlags, Pointer lpSource, int dwMessageId, int dwLanguageId, PointerByReference lpBuffer, int nSize, Pointer va_list); int FormatMessage(int dwFlags, Pointer lpSource, int dwMessageId, int dwLanguageId, Buffer lpBuffer, int nSize, Pointer va_list); int FILE_LIST_DIRECTORY = 0x00000001; int FILE_SHARE_READ = 1; int FILE_SHARE_WRITE = 2; int FILE_SHARE_DELETE = 4; int CREATE_NEW = 1; int CREATE_ALWAYS = 2; int OPEN_EXISTING = 3; int OPEN_ALWAYS = 4; int TRUNCATE_EXISTING = 5; int FILE_FLAG_WRITE_THROUGH = 0x80000000; int FILE_FLAG_OVERLAPPED = 0x40000000; int FILE_FLAG_NO_BUFFERING = 0x20000000; int FILE_FLAG_RANDOM_ACCESS = 0x10000000; int FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000; int FILE_FLAG_DELETE_ON_CLOSE = 0x04000000; int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000; int FILE_FLAG_POSIX_SEMANTICS = 0x01000000; int FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000; int FILE_FLAG_OPEN_NO_RECALL = 0x00100000; int FILE_ATTRIBUTE_READONLY = 0x00000001; int FILE_ATTRIBUTE_HIDDEN = 0x00000002; int FILE_ATTRIBUTE_SYSTEM = 0x00000004; int FILE_ATTRIBUTE_DIRECTORY = 0x00000010; int FILE_ATTRIBUTE_ARCHIVE = 0x00000020; int FILE_ATTRIBUTE_DEVICE = 0x00000040; int FILE_ATTRIBUTE_NORMAL = 0x00000080; int FILE_ATTRIBUTE_TEMPORARY = 0x00000100; int FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200; int FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400; int FILE_ATTRIBUTE_COMPRESSED = 0x00000800; int FILE_ATTRIBUTE_OFFLINE = 0x00001000; int FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000; int FILE_ATTRIBUTE_ENCRYPTED = 0x00004000; int DRIVE_UNKNOWN = 0; int DRIVE_NO_ROOT_DIR = 1; int DRIVE_REMOVABLE = 2; int DRIVE_FIXED = 3; int DRIVE_REMOTE = 4; int DRIVE_CDROM = 5; int DRIVE_RAMDISK = 6; int GENERIC_WRITE = 0x40000000; int GENERIC_READ = 0x80000000; class SECURITY_ATTRIBUTES extends Structure { public int nLength = size(); public Pointer lpSecurityDescriptor; public boolean bInheritHandle; } HANDLE CreateFile(String lpFileName, int dwDesiredAccess, int dwShareMode, SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, HANDLE hTemplateFile); boolean CreateDirectory(); HANDLE CreateIoCompletionPort(HANDLE FileHandle, HANDLE ExistingCompletionPort, Pointer CompletionKey, int NumberOfConcurrentThreads); int INFINITE = 0xFFFFFFFF; boolean GetQueuedCompletionStatus(HANDLE CompletionPort, IntByReference lpNumberOfBytes, ByReference lpCompletionKey, PointerByReference lpOverlapped, int dwMilliseconds); boolean PostQueuedCompletionStatus(HANDLE CompletionPort, int dwNumberOfBytesTransferred, Pointer dwCompletionKey, OVERLAPPED lpOverlapped); static final int WAIT_FAILED = 0xFFFFFFFF; static final int WAIT_OBJECT_0 = 0; int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds); boolean DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, HANDLEByReference lpTargetHandle, int dwDesiredAccess, boolean bInheritHandle, int dwOptions); boolean CloseHandle(HANDLE hObject); int FILE_ACTION_ADDED = 1; int FILE_ACTION_REMOVED = 2; int FILE_ACTION_MODIFIED = 3; int FILE_ACTION_RENAMED_OLD_NAME = 4; int FILE_ACTION_RENAMED_NEW_NAME = 5; int FILE_NOTIFY_CHANGE_FILE_NAME = 1; int FILE_NOTIFY_CHANGE_DIR_NAME = 2; int FILE_NOTIFY_CHANGE_NAME = 3; int FILE_NOTIFY_CHANGE_ATTRIBUTES = 4; int FILE_NOTIFY_CHANGE_SIZE = 8; int FILE_NOTIFY_CHANGE_LAST_WRITE = 16; int FILE_NOTIFY_CHANGE_LAST_ACCESS = 32; int FILE_NOTIFY_CHANGE_CREATION = 64; int FILE_NOTIFY_CHANGE_EA = 128; int FILE_NOTIFY_CHANGE_SECURITY = 256; int FILE_NOTIFY_CHANGE_STREAM_NAME = 512; int FILE_NOTIFY_CHANGE_STREAM_SIZE = 1024; int FILE_NOTIFY_CHANGE_STREAM_WRITE = 2048; /** * This structure is non-trivial since it is a pattern stamped into a large * block of result memory rather than something that stands alone or is used * for input. */ class FILE_NOTIFY_INFORMATION extends Structure { public int NextEntryOffset; public int Action; public int FileNameLength; // filename is not nul-terminated, so we can't use a String/WString public char[] FileName = new char[1]; private FILE_NOTIFY_INFORMATION() { } @SuppressWarnings("nls") public FILE_NOTIFY_INFORMATION(final int size) { if (size < size()) { throw new IllegalArgumentException("Size must greater than " + size() + ", requested " + size); } allocateMemory(size); } /** * WARNING: this filename may be either the short or long form of the * filename. */ public String getFilename() { return new String(FileName, 0, FileNameLength / 2); } @Override public void read() { // avoid reading filename until we know how long it is FileName = new char[0]; super.read(); FileName = getPointer().getCharArray(12, FileNameLength / 2); } public FILE_NOTIFY_INFORMATION next() { if (NextEntryOffset == 0) { return null; } final FILE_NOTIFY_INFORMATION next = new FILE_NOTIFY_INFORMATION(); next.useMemory(getPointer(), NextEntryOffset); next.read(); return next; } } class OVERLAPPED extends Structure { public ULONG_PTR Internal; public ULONG_PTR InternalHigh; public int Offset; public int OffsetHigh; public HANDLE hEvent; } // TODO: figure out how OVERLAPPED is used and apply an appropriate mapping interface OVERLAPPED_COMPLETION_ROUTINE extends StdCallCallback { void callback(int errorCode, int nBytesTransferred, OVERLAPPED overlapped); } /** * NOTE: only exists in unicode form (W suffix). Define this method * explicitly with the W suffix to avoid inadvertent calls in ASCII mode. */ boolean ReadDirectoryChangesW(HANDLE directory, FILE_NOTIFY_INFORMATION info, int length, boolean watchSubtree, int notifyFilter, IntByReference bytesReturned, OVERLAPPED overlapped, OVERLAPPED_COMPLETION_ROUTINE completionRoutine); /** * ASCII version. Use {@link Native#toString(byte[])} to obtain the short * path from the <code>byte</code> array. Use only if * <code>w32.ascii==true</code>. */ int GetShortPathName(String lpszLongPath, byte[] lpdzShortPath, int cchBuffer); /** * Unicode version (the default). Use {@link Native#toString(char[])} to * obtain the short path from the <code>char</code> array. */ int GetShortPathName(String lpszLongPath, char[] lpdzShortPath, int cchBuffer); /** * * Conversion code in this class Copyright 2002-2004 Apache Software * Foundation. * * @author Rainer Klute (klute@rainer-klute.de) for the Apache Software * Foundation (org.apache.poi.hpsf) */ static class FILETIME extends Structure { public int dwLowDateTime; public int dwHighDateTime; /** * <p> * The difference between the Windows epoch (1601-01-01 00:00:00) and * the Unix epoch (1970-01-01 00:00:00) in milliseconds: * 11644473600000L. (Use your favorite spreadsheet program to verify the * correctness of this value. By the way, did you notice that you can * tell from the epochs which operating system is the modern one? :-)) * </p> */ private static final long EPOCH_DIFF = 11644473600000L; /** * <p> * Converts a Windows FILETIME into a {@link Date}. The Windows FILETIME * structure holds a date and time associated with a file. The structure * identifies a 64-bit integer specifying the number of 100-nanosecond * intervals which have passed since January 1, 1601. This 64-bit value * is split into the two double words stored in the structure. * </p> * * @param high * The higher double word of the FILETIME structure. * @param low * The lower double word of the FILETIME structure. * @return The Windows FILETIME as a {@link Date}. */ public static Date filetimeToDate(final int high, final int low) { final long filetime = (long) high << 32 | low & 0xffffffffL; final long ms_since_16010101 = filetime / (1000 * 10); final long ms_since_19700101 = ms_since_16010101 - EPOCH_DIFF; return new Date(ms_since_19700101); } /** * <p> * Converts a {@link Date} into a filetime. * </p> * * @param date * The date to be converted * @return The filetime * * @see #filetimeToDate */ public static long dateToFileTime(final Date date) { final long ms_since_19700101 = date.getTime(); final long ms_since_16010101 = ms_since_19700101 + EPOCH_DIFF; return ms_since_16010101 * 1000 * 10; } public Date toDate() { return filetimeToDate(dwHighDateTime, dwLowDateTime); } public long toLong() { return toDate().getTime(); } @Override public String toString() { return super.toString() + ": " + toDate().toString(); //$NON-NLS-1$ } } int LMEM_ZEROINIT = 0x0040; int LMEM_FIXED = 0x0000; int LPTR = LMEM_FIXED | LMEM_ZEROINIT; Pointer LocalAlloc(int type, int cbInput); boolean WriteFile(HANDLE hFile, byte[] lpBuffer, int nNumberOfBytesToWrite, IntByReference lpNumberOfBytesWritten, OVERLAPPED lpOverlapped); HANDLE CreateEvent(SECURITY_ATTRIBUTES lpEventAttributes, boolean bManualReset, boolean bInitialState, String lpName); boolean SetEvent(HANDLE hEvent); boolean PulseEvent(HANDLE hEvent); int PAGE_READONLY = 0x02; int PAGE_READWRITE = 0x04; int PAGE_WRITECOPY = 0x08; int PAGE_EXECUTE = 0x10; int PAGE_EXECUTE_READ = 0x20; int PAGE_EXECUTE_READWRITE = 0x40; HANDLE CreateFileMapping(HANDLE hFile, SECURITY_ATTRIBUTES lpAttributes, int flProtect, int dwMaximumSizeHigh, int dwMaximumSizeLow, String lpName); int SECTION_QUERY = 0x0001; int SECTION_MAP_WRITE = 0x0002; int SECTION_MAP_READ = 0x0004; int SECTION_MAP_EXECUTE = 0x0008; int SECTION_EXTEND_SIZE = 0x0010; Pointer MapViewOfFile(HANDLE hFileMappingObject, int dwDesiredAccess, int dwFileOffsetHigh, int dwFileOffsetLow, int dwNumberOfBytesToMap); boolean UnmapViewOfFile(Pointer lpBaseAddress); int PROCESS_QUERY_INFORMATION = 0x0400; int PROCESS_VM_READ = 0x0010; int PROCESS_VM_WRITE = 0x0020; int PROCESS_VM_OPERATION = 0x0008; HANDLE OpenProcess(int dwDesiredAccess, boolean bInheritHandle, int dwProcessId); boolean ReadProcessMemory(HANDLE hProcess, Pointer lpBaseAddress, Memory lpBuffer, SIZE_T nSize, IntByReference dwNumberOfBytesRead); boolean ReadProcessMemory(HANDLE hProcess, Pointer lpBaseAddress, Pointer lpBuffer, SIZE_T nSize, IntByReference dwNumberOfBytesRead); boolean ReadProcessMemory(HANDLE hProcess, int lpBaseAddress, Pointer lpBuffer, SIZE_T nSize, IntByReference dwNumberOfBytesRead); boolean ReadProcessMemory(HANDLE hProcess, int lpBaseAddress, byte[] lpBuffer, SIZE_T nSize, IntByReference dwNumberOfBytesRead); boolean ReadProcessMemory(HANDLE hProcess, int lpBaseAddress, ByReference lpBuffer, SIZE_T nSize, IntByReference dwNumberOfBytesRead); boolean WriteProcessMemory(HANDLE hProcess, Pointer lpBaseAddress, Pointer lpBuffer, SIZE_T nSize, IntByReference lpNumberOfBytesWritten); boolean WriteProcessMemory(HANDLE hProcess, int lpBaseAddress, Pointer lpBuffer, SIZE_T nSize, IntByReference lpNumberOfBytesWritten); int MEM_COMMIT = 0x1000; int MEM_RESERVE = 0x2000; int FILE_MAP_WRITE = SECTION_MAP_WRITE; int FILE_MAP_READ = SECTION_MAP_READ; int MEM_RELEASE = 0x8000; int VirtualAllocEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, int flAllocationType, int flProtect); boolean VirtualFreeEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, int dwFreeType); boolean VirtualFreeEx(HANDLE hProcess, int lpAddress, SIZE_T dwSize, int dwFreeType); boolean VirtualFreeEx(HANDLE hProcess, int lpAddress, int dwSize, int dwFreeType); int TH32CS_INHERIT = 0x80000000; int TH32CS_SNAPHEAPLIST = 0x00000001; int TH32CS_SNAPPROCESS = 0x00000002; int TH32CS_SNAPTHREAD = 0x00000004; int TH32CS_SNAPMODULE = 0x00000008; int TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD; int MAX_PATH = 260; HANDLE CreateToolhelp32Snapshot(int dwFlags, int th32ProcessID); int MAX_MODULE_NAME32 = 255; class MODULEENTRY32W extends Structure { public int dwSize = size(); public int th32ModuleID; public int th32ProcessID; public int GlblcntUsage; public int ProccntUsage; public int modBaseAddr; public int modBaseSize; public HMODULE hModule; public char szModule[] = new char[MAX_MODULE_NAME32 + 1]; public char szExePath[] = new char[MAX_PATH]; } boolean Module32First(HANDLE hSnapshot, MODULEENTRY32W lpme); boolean Module32Next(HANDLE hSnapshot, MODULEENTRY32W lpme); }