/* 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.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);
}