/* 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);
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;
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);
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() { }
public FILE_NOTIFY_INFORMATION(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);
}
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;
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();
}
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);
}