jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java
changeset 2057 3acf8e5e2ca0
child 2071 5e6af6d106cb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java	Sun Feb 15 12:25:54 2009 +0000
@@ -0,0 +1,1133 @@
+/*
+ * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.nio.fs;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.misc.Unsafe;
+
+/**
+ * Win32 and library calls.
+ */
+
+class WindowsNativeDispatcher {
+    private WindowsNativeDispatcher() { }
+
+    /**
+     * HANDLE CreateFile(
+     *   LPCTSTR lpFileName,
+     *   DWORD dwDesiredAccess,
+     *   DWORD dwShareMode,
+     *   LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+     *   DWORD dwCreationDisposition,
+     *   DWORD dwFlagsAndAttributes,
+     *   HANDLE hTemplateFile
+     * )
+     */
+    static long CreateFile(String path,
+                           int dwDesiredAccess,
+                           int dwShareMode,
+                           long lpSecurityAttributes,
+                           int dwCreationDisposition,
+                           int dwFlagsAndAttributes)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return CreateFile0(buffer.address(),
+                               dwDesiredAccess,
+                               dwShareMode,
+                               lpSecurityAttributes,
+                               dwCreationDisposition,
+                               dwFlagsAndAttributes);
+        } finally {
+            buffer.release();
+        }
+    }
+    static long CreateFile(String path,
+                           int dwDesiredAccess,
+                           int dwShareMode,
+                           int dwCreationDisposition,
+                           int dwFlagsAndAttributes)
+        throws WindowsException
+    {
+        return CreateFile(path, dwDesiredAccess, dwShareMode, 0L,
+                          dwCreationDisposition, dwFlagsAndAttributes);
+    }
+    private static native long CreateFile0(long lpFileName,
+                                           int dwDesiredAccess,
+                                           int dwShareMode,
+                                           long lpSecurityAttributes,
+                                           int dwCreationDisposition,
+                                           int dwFlagsAndAttributes)
+        throws WindowsException;
+
+    /**
+     * CloseHandle(
+     *   HANDLE hObject
+     * )
+     */
+    static native void CloseHandle(long handle);
+
+    /**
+     * DeleteFile(
+     *   LPCTSTR lpFileName
+     * )
+     */
+    static void DeleteFile(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            DeleteFile0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void DeleteFile0(long lpFileName)
+        throws WindowsException;
+
+    /**
+     * CreateDirectory(
+     *   LPCTSTR lpPathName,
+     *   LPSECURITY_ATTRIBUTES lpSecurityAttributes
+     * )
+     */
+    static void CreateDirectory(String path, long lpSecurityAttributes) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            CreateDirectory0(buffer.address(), lpSecurityAttributes);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void CreateDirectory0(long lpFileName, long lpSecurityAttributes)
+        throws WindowsException;
+
+    /**
+     * RemoveDirectory(
+     *   LPCTSTR lpPathName
+     * )
+     */
+    static void RemoveDirectory(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            RemoveDirectory0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void RemoveDirectory0(long lpFileName)
+        throws WindowsException;
+
+    /**
+     * Marks a file as a sparse file.
+     *
+     * DeviceIoControl(
+     *   FSCTL_SET_SPARSE
+     * )
+     */
+    static native void DeviceIoControlSetSparse(long handle)
+        throws WindowsException;
+
+    /**
+     * Retrieves the reparse point data associated with the file or directory.
+     *
+     * DeviceIoControl(
+     *   FSCTL_GET_REPARSE_POINT
+     * )
+     */
+    static native void DeviceIoControlGetReparsePoint(long handle,
+        long bufferAddress, int bufferSize) throws WindowsException;
+
+    /**
+     * HANDLE FindFirstFile(
+     *   LPCTSTR lpFileName,
+     *   LPWIN32_FIND_DATA lpFindFileData
+     * )
+     */
+    static FirstFile FindFirstFile(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            FirstFile data = new FirstFile();
+            FindFirstFile0(buffer.address(), data);
+            return data;
+        } finally {
+            buffer.release();
+        }
+    }
+    static class FirstFile {
+        private long handle;
+        private String name;
+
+        private FirstFile() { }
+        public long handle()    { return handle; }
+        public String name()    { return name; }
+    }
+    private static native void FindFirstFile0(long lpFileName, FirstFile obj)
+        throws WindowsException;
+
+    /**
+     * HANDLE FindFirstFile(
+     *   LPCTSTR lpFileName,
+     *   LPWIN32_FIND_DATA lpFindFileData
+     * )
+     */
+    static long FindFirstFile(String path, long address) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return FindFirstFile1(buffer.address(), address);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native long FindFirstFile1(long lpFileName, long address)
+        throws WindowsException;
+
+    /**
+     * FindNextFile(
+     *   HANDLE hFindFile,
+     *   LPWIN32_FIND_DATA lpFindFileData
+     * )
+     *
+     * @return  lpFindFileData->cFileName
+     */
+    static native String FindNextFile(long handle) throws WindowsException;
+
+    /**
+     * HANDLE FindFirstStreamW(
+     *   LPCWSTR lpFileName,
+     *   STREAM_INFO_LEVELS InfoLevel,
+     *   LPVOID lpFindStreamData,
+     *   DWORD dwFlags
+     * )
+     */
+    static FirstStream FindFirstStream(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            FirstStream data = new FirstStream();
+            FindFirstStream0(buffer.address(), data);
+            if (data.handle() == WindowsConstants.INVALID_HANDLE_VALUE)
+                return null;
+            return data;
+        } finally {
+            buffer.release();
+        }
+    }
+    static class FirstStream {
+        private long handle;
+        private String name;
+
+        private FirstStream() { }
+        public long handle()    { return handle; }
+        public String name()    { return name; }
+    }
+    private static native void FindFirstStream0(long lpFileName, FirstStream obj)
+        throws WindowsException;
+
+    /*
+     * FindNextStreamW(
+     *   HANDLE hFindStream,
+     *   LPVOID lpFindStreamData
+     * )
+     */
+    static native String FindNextStream(long handle) throws WindowsException;
+
+    /**
+     * FindClose(
+     *   HANDLE hFindFile
+     * )
+     */
+    static native void FindClose(long handle) throws WindowsException;
+
+    /**
+     * GetFileInformationByHandle(
+     *   HANDLE hFile,
+     *   LPBY_HANDLE_FILE_INFORMATION lpFileInformation
+     * )
+     */
+    static native void GetFileInformationByHandle(long handle, long address)
+        throws WindowsException;
+
+    /**
+     * CopyFileEx(
+     *   LPCWSTR lpExistingFileName
+     *   LPCWSTR lpNewFileName,
+     *   LPPROGRESS_ROUTINE lpProgressRoutine
+     *   LPVOID lpData,
+     *   LPBOOL pbCancel,
+     *   DWORD dwCopyFlags
+     * )
+     */
+    static void CopyFileEx(String source, String target, int flags,
+                           long addressToPollForCancel)
+        throws WindowsException
+    {
+        NativeBuffer sourceBuffer = asNativeBuffer(source);
+        NativeBuffer targetBuffer = asNativeBuffer(target);
+        try {
+            CopyFileEx0(sourceBuffer.address(), targetBuffer.address(), flags,
+                        addressToPollForCancel);
+        } finally {
+            targetBuffer.release();
+            sourceBuffer.release();
+        }
+    }
+    private static native void CopyFileEx0(long existingAddress, long newAddress,
+        int flags, long addressToPollForCancel) throws WindowsException;
+
+    /**
+     * MoveFileEx(
+     *   LPCTSTR lpExistingFileName,
+     *   LPCTSTR lpNewFileName,
+     *   DWORD dwFlags
+     * )
+     */
+    static void MoveFileEx(String source, String target, int flags)
+        throws WindowsException
+    {
+        NativeBuffer sourceBuffer = asNativeBuffer(source);
+        NativeBuffer targetBuffer = asNativeBuffer(target);
+        try {
+            MoveFileEx0(sourceBuffer.address(), targetBuffer.address(), flags);
+        } finally {
+            targetBuffer.release();
+            sourceBuffer.release();
+        }
+    }
+    private static native void MoveFileEx0(long existingAddress, long newAddress,
+        int flags) throws WindowsException;
+
+    /**
+     * DWORD GetFileAttributes(
+     *   LPCTSTR lpFileName
+     * )
+     */
+    static int GetFileAttributes(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return GetFileAttributes0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int GetFileAttributes0(long lpFileName)
+        throws WindowsException;
+
+    /**
+     * SetFileAttributes(
+     *   LPCTSTR lpFileName,
+     *   DWORD dwFileAttributes
+     */
+    static void SetFileAttributes(String path, int dwFileAttributes)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            SetFileAttributes0(buffer.address(), dwFileAttributes);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void SetFileAttributes0(long lpFileName,
+        int dwFileAttributes) throws WindowsException;
+
+    /**
+     * GetFileAttributesEx(
+     *   LPCTSTR lpFileName,
+     *   GET_FILEEX_INFO_LEVELS fInfoLevelId,
+     *   LPVOID lpFileInformation
+     * );
+     */
+    static void GetFileAttributesEx(String path, long address) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            GetFileAttributesEx0(buffer.address(), address);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native void GetFileAttributesEx0(long lpFileName, long address)
+        throws WindowsException;
+    /**
+     * SetFileTime(
+     *   HANDLE hFile,
+     *   CONST FILETIME *lpCreationTime,
+     *   CONST FILETIME *lpLastAccessTime,
+     *   CONST FILETIME *lpLastWriteTime
+     * )
+     */
+    static native void SetFileTime(long handle, long createTime,
+        long lastAccessTime, long lastWriteTime) throws WindowsException;
+
+    /**
+     * SetEndOfFile(
+     *   HANDLE hFile
+     * )
+     */
+    static native void SetEndOfFile(long handle) throws WindowsException;
+
+    /**
+     * DWORD GetLogicalDrives(VOID)
+     */
+    static native int GetLogicalDrives() throws WindowsException;
+
+    /**
+     * GetVolumeInformation(
+     *   LPCTSTR lpRootPathName,
+     *   LPTSTR lpVolumeNameBuffer,
+     *   DWORD nVolumeNameSize,
+     *   LPDWORD lpVolumeSerialNumber,
+     *   LPDWORD lpMaximumComponentLength,
+     *   LPDWORD lpFileSystemFlags,
+     *   LPTSTR lpFileSystemNameBuffer,
+     *   DWORD nFileSystemNameSize
+     * )
+     */
+    static VolumeInformation GetVolumeInformation(String root)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(root);
+        try {
+            VolumeInformation info = new VolumeInformation();
+            GetVolumeInformation0(buffer.address(), info);
+            return info;
+        } finally {
+            buffer.release();
+        }
+    }
+    static class VolumeInformation {
+        private String fileSystemName;
+        private String volumeName;
+        private int volumeSerialNumber;
+        private int flags;
+        private VolumeInformation() { }
+
+        public String fileSystemName()      { return fileSystemName; }
+        public String volumeName()          { return volumeName; }
+        public int volumeSerialNumber()     { return volumeSerialNumber; }
+        public int flags()                  { return flags; }
+    }
+    private static native void GetVolumeInformation0(long lpRoot,
+                                                     VolumeInformation obj)
+        throws WindowsException;
+
+    /**
+     * UINT GetDriveType(
+     *   LPCTSTR lpRootPathName
+     * )
+     */
+    static int GetDriveType(String root) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(root);
+        try {
+            return GetDriveType0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int GetDriveType0(long lpRoot) throws WindowsException;
+
+    /**
+     * GetDiskFreeSpaceEx(
+     *   LPCTSTR lpDirectoryName,
+     *   PULARGE_INTEGER lpFreeBytesAvailableToCaller,
+     *   PULARGE_INTEGER lpTotalNumberOfBytes,
+     *   PULARGE_INTEGER lpTotalNumberOfFreeBytes
+     * )
+     */
+    static DiskFreeSpace GetDiskFreeSpaceEx(String path)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            DiskFreeSpace space = new DiskFreeSpace();
+            GetDiskFreeSpaceEx0(buffer.address(), space);
+            return space;
+        } finally {
+            buffer.release();
+        }
+    }
+    static class DiskFreeSpace {
+        private long freeBytesAvailable;
+        private long totalNumberOfBytes;
+        private long totalNumberOfFreeBytes;
+        private DiskFreeSpace() { }
+
+        public long freeBytesAvailable()      { return freeBytesAvailable; }
+        public long totalNumberOfBytes()      { return totalNumberOfBytes; }
+        public long totalNumberOfFreeBytes()  { return totalNumberOfFreeBytes; }
+    }
+    private static native void GetDiskFreeSpaceEx0(long lpDirectoryName,
+                                                   DiskFreeSpace obj)
+        throws WindowsException;
+
+
+    /**
+     * GetVolumePathName(
+     *   LPCTSTR lpszFileName,
+     *   LPTSTR lpszVolumePathName,
+     *   DWORD cchBufferLength
+     * )
+     *
+     * @return  lpFileName
+     */
+    static String GetVolumePathName(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return GetVolumePathName0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native String GetVolumePathName0(long lpFileName)
+        throws WindowsException;
+
+
+    /**
+     * InitializeSecurityDescriptor(
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
+     *   DWORD dwRevision
+     * )
+     */
+    static native void InitializeSecurityDescriptor(long sdAddress)
+        throws WindowsException;
+
+    /**
+     * InitializeAcl(
+     *   PACL pAcl,
+     *   DWORD nAclLength,
+     *   DWORD dwAclRevision
+     * )
+     */
+    static native void InitializeAcl(long aclAddress, int size)
+         throws WindowsException;
+
+    /**
+     * GetFileSecurity(
+     *   LPCTSTR lpFileName,
+     *   SECURITY_INFORMATION RequestedInformation,
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
+     *   DWORD nLength,
+     *   LPDWORD lpnLengthNeeded
+     * )
+     */
+    static int GetFileSecurity(String path,
+                               int requestedInformation,
+                               long pSecurityDescriptor,
+                               int nLength) throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return GetFileSecurity0(buffer.address(), requestedInformation,
+                pSecurityDescriptor, nLength);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int GetFileSecurity0(long lpFileName,
+                                               int requestedInformation,
+                                               long pSecurityDescriptor,
+                                               int nLength) throws WindowsException;
+
+    /**
+     * SetFileSecurity(
+     *   LPCTSTR lpFileName,
+     *   SECURITY_INFORMATION SecurityInformation,
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor
+     * )
+     */
+    static void SetFileSecurity(String path,
+                                int securityInformation,
+                                long pSecurityDescriptor)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            SetFileSecurity0(buffer.address(), securityInformation,
+                pSecurityDescriptor);
+        } finally {
+            buffer.release();
+        }
+    }
+    static native void SetFileSecurity0(long lpFileName, int securityInformation,
+        long pSecurityDescriptor) throws WindowsException;
+
+    /**
+     * GetSecurityDescriptorOwner(
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor
+     *   PSID *pOwner,
+     *   LPBOOL lpbOwnerDefaulted
+     * )
+     *
+     * @return  pOwner
+     */
+    static native long GetSecurityDescriptorOwner(long pSecurityDescriptor)
+        throws WindowsException;
+
+    /**
+     * SetSecurityDescriptorOwner(
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
+     *   PSID pOwner,
+     *   BOOL bOwnerDefaulted
+     * )
+     */
+    static native void SetSecurityDescriptorOwner(long pSecurityDescriptor,
+                                                  long pOwner)
+        throws WindowsException;
+
+    /**
+     * GetSecurityDescriptorDacl(
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
+     *   LPBOOL lpbDaclPresent,
+     *   PACL *pDacl,
+     *   LPBOOL lpbDaclDefaulted
+     * )
+     */
+    static native long GetSecurityDescriptorDacl(long pSecurityDescriptor);
+
+    /**
+     * SetSecurityDescriptorDacl(
+     *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
+     *   BOOL bDaclPresent,
+     *   PACL pDacl,
+     *   BOOL bDaclDefaulted
+     * )
+     */
+    static native void SetSecurityDescriptorDacl(long pSecurityDescriptor, long pAcl)
+        throws WindowsException;
+
+
+    /**
+     * GetAclInformation(
+     *   PACL pAcl,
+     *   LPVOID pAclInformation,
+     *   DWORD nAclInformationLength,
+     *   ACL_INFORMATION_CLASS dwAclInformationClass
+     * )
+     */
+    static AclInformation GetAclInformation(long aclAddress) {
+        AclInformation info = new AclInformation();
+        GetAclInformation0(aclAddress, info);
+        return info;
+    }
+    static class AclInformation {
+        private int aceCount;
+        private AclInformation() { }
+
+        public int aceCount()   { return aceCount; }
+    }
+    private static native void GetAclInformation0(long aclAddress,
+        AclInformation obj);
+
+    /**
+     * GetAce(
+     *   PACL pAcl,
+     *   DWORD dwAceIndex,
+     *   LPVOID *pAce
+     * )
+     */
+    static native long GetAce(long aclAddress, int aceIndex);
+
+    /**
+     * AddAccessAllowedAceEx(
+     *   PACL pAcl,
+     *   DWORD dwAceRevision,
+     *   DWORD AceFlags,
+     *   DWORD AccessMask,
+     *   PSID pSid
+     * )
+     */
+    static native void AddAccessAllowedAceEx(long aclAddress, int flags,
+        int mask, long sidAddress) throws WindowsException;
+
+    /**
+     * AddAccessDeniedAceEx(
+     *   PACL pAcl,
+     *   DWORD dwAceRevision,
+     *   DWORD AceFlags,
+     *   DWORD AccessMask,
+     *   PSID pSid
+     * )
+     */
+    static native void AddAccessDeniedAceEx(long aclAddress, int flags,
+        int mask, long sidAddress) throws WindowsException;
+
+    /**
+     * LookupAccountSid(
+     *   LPCTSTR lpSystemName,
+     *   PSID Sid,
+     *   LPTSTR Name,
+     *   LPDWORD cbName,
+     *   LPTSTR ReferencedDomainName,
+     *   LPDWORD cbReferencedDomainName,
+     *   PSID_NAME_USE peUse
+     * )
+     */
+    static Account LookupAccountSid(long sidAddress) throws WindowsException {
+        Account acc = new Account();
+        LookupAccountSid0(sidAddress, acc);
+        return acc;
+    }
+    static class Account {
+        private String domain;
+        private String name;
+        private int use;
+        private Account() { }
+
+        public String domain()  { return domain; }
+        public String name()    { return name; }
+        public int use()        { return use; }
+    }
+    private static native void LookupAccountSid0(long sidAddress, Account obj)
+        throws WindowsException;
+
+    /**
+     * LookupAccountName(
+     *   LPCTSTR lpSystemName,
+     *   LPCTSTR lpAccountName,
+     *   PSID Sid,
+     *   LPDWORD cbSid,
+     *   LPTSTR ReferencedDomainName,
+     *   LPDWORD cbReferencedDomainName,
+     *   PSID_NAME_USE peUse
+     * )
+     *
+     * @return  cbSid
+     */
+    static int LookupAccountName(String accountName,
+                                 long pSid,
+                                 int cbSid) throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(accountName);
+        try {
+            return LookupAccountName0(buffer.address(), pSid, cbSid);
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native int LookupAccountName0(long lpAccountName, long pSid,
+        int cbSid) throws WindowsException;
+
+    /**
+     * DWORD GetLengthSid(
+     *   PSID pSid
+     * )
+     */
+    static native int GetLengthSid(long sidAddress);
+
+    /**
+     * ConvertSidToStringSid(
+     *   PSID Sid,
+     *   LPTSTR* StringSid
+     * )
+     *
+     * @return  StringSid
+     */
+    static native String ConvertSidToStringSid(long sidAddress)
+        throws WindowsException;
+
+    /**
+     * ConvertStringSidToSid(
+     *   LPCTSTR StringSid,
+     *   PSID* pSid
+     * )
+     *
+     * @return  pSid
+     */
+    static long ConvertStringSidToSid(String sidString)
+        throws WindowsException
+    {
+        NativeBuffer buffer = asNativeBuffer(sidString);
+        try {
+            return ConvertStringSidToSid0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native long ConvertStringSidToSid0(long lpStringSid)
+        throws WindowsException;
+
+    /**
+     * HANDLE GetCurrentProcess(VOID)
+     */
+    static native long GetCurrentProcess();
+
+    /**
+     * HANDLE GetCurrentThread(VOID)
+     */
+    static native long GetCurrentThread();
+
+    /**
+     * OpenProcessToken(
+     *   HANDLE ProcessHandle,
+     *   DWORD DesiredAccess,
+     *   PHANDLE TokenHandle
+     * )
+     */
+    static native long OpenProcessToken(long hProcess, int desiredAccess)
+        throws WindowsException;
+
+    /**
+     * OpenThreadToken(
+     *   HANDLE ThreadHandle,
+     *   DWORD DesiredAccess,
+     *   BOOL OpenAsSelf,
+     *   PHANDLE TokenHandle
+     * )
+     */
+    static native long OpenThreadToken(long hThread, int desiredAccess,
+        boolean openAsSelf) throws WindowsException;
+
+    /**
+     */
+    static native long DuplicateTokenEx(long hThread, int desiredAccess)
+        throws WindowsException;
+
+    /**
+     * SetThreadToken(
+     *   PHANDLE Thread,
+     *   HANDLE Token
+     * )
+     */
+    static native void SetThreadToken(long thread, long hToken)
+        throws WindowsException;
+
+    /**
+     * GetTokenInformation(
+     *   HANDLE TokenHandle,
+     *   TOKEN_INFORMATION_CLASS TokenInformationClass,
+     *   LPVOID TokenInformation,
+     *   DWORD TokenInformationLength,
+     *   PDWORD ReturnLength
+     * )
+     */
+    static native int GetTokenInformation(long token, int tokenInfoClass,
+        long pTokenInfo, int tokenInfoLength) throws WindowsException;
+
+    /**
+     * AdjustTokenPrivileges(
+     *   HANDLE TokenHandle,
+     *   BOOL DisableAllPrivileges
+     *   PTOKEN_PRIVILEGES NewState
+     *   DWORD BufferLength
+     *   PTOKEN_PRIVILEGES
+     *   PDWORD ReturnLength
+     * )
+     */
+    static native void AdjustTokenPrivileges(long token, long luid, int attributes)
+        throws WindowsException;
+
+    /**
+     */
+    static long LookupPrivilegeValue(String name) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(name);
+        try {
+            return LookupPrivilegeValue0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native long LookupPrivilegeValue0(long lpName)
+        throws WindowsException;
+
+    /**
+     * BuildTrusteeWithSid(
+     *   PTRUSTEE pTrustee,
+     *   PSID pSid
+     * )
+     *
+     * @return  pTrustee
+     */
+    static native long BuildTrusteeWithSid(long pSid);
+
+    /**
+     * GetEffectiveRightsFromAcl(
+     *   PACL pacl,
+     *   PTRUSTEE pTrustee,
+     *   PACCESS_MASK pAccessRights
+     * )
+     *
+     * @return  AccessRights
+     */
+    static native int GetEffectiveRightsFromAcl(long pAcl, long pTrustee)
+        throws WindowsException;
+
+    /**
+     * CreateSymbolicLink(
+     *   LPCWSTR lpSymlinkFileName,
+     *   LPCWSTR lpTargetFileName,
+     *   DWORD dwFlags
+     * )
+     */
+    static void CreateSymbolicLink(String link, String target, int flags)
+        throws WindowsException
+    {
+        NativeBuffer linkBuffer = asNativeBuffer(link);
+        NativeBuffer targetBuffer = asNativeBuffer(target);
+        try {
+            CreateSymbolicLink0(linkBuffer.address(), targetBuffer.address(),
+                                flags);
+        } finally {
+            targetBuffer.release();
+            linkBuffer.release();
+        }
+    }
+    private static native void CreateSymbolicLink0(long linkAddress,
+        long targetAddress, int flags) throws WindowsException;
+
+    /**
+     * CreateHardLink(
+     *    LPCTSTR lpFileName,
+     *    LPCTSTR lpExistingFileName,
+     *    LPSECURITY_ATTRIBUTES lpSecurityAttributes
+     * )
+     */
+    static void CreateHardLink(String newFile, String existingFile)
+        throws WindowsException
+    {
+        NativeBuffer newFileBuffer = asNativeBuffer(newFile);
+        NativeBuffer existingFileBuffer = asNativeBuffer(existingFile);
+        try {
+            CreateHardLink0(newFileBuffer.address(), existingFileBuffer.address());
+        } finally {
+            existingFileBuffer.release();
+            newFileBuffer.release();
+        }
+    }
+    private static native void CreateHardLink0(long newFileBuffer,
+        long existingFiletBuffer) throws WindowsException;
+
+    /**
+     * GetFullPathName(
+     *   LPCTSTR lpFileName,
+     *   DWORD nBufferLength,
+     *   LPTSTR lpBuffer,
+     *   LPTSTR *lpFilePart
+     * )
+     */
+    static String GetFullPathName(String path) throws WindowsException {
+        NativeBuffer buffer = asNativeBuffer(path);
+        try {
+            return GetFullPathName0(buffer.address());
+        } finally {
+            buffer.release();
+        }
+    }
+    private static native String GetFullPathName0(long pathAddress)
+        throws WindowsException;
+
+    /**
+     * GetFinalPathNameByHandle(
+     *   HANDLE hFile,
+     *   LPTSTR lpszFilePath,
+     *   DWORD cchFilePath,
+     *   DWORD dwFlags
+     * )
+     */
+    static native String GetFinalPathNameByHandle(long handle)
+        throws WindowsException;
+
+    /**
+     * FormatMessage(
+     *   DWORD dwFlags,
+     *   LPCVOID lpSource,
+     *   DWORD dwMessageId,
+     *   DWORD dwLanguageId,
+     *   LPTSTR lpBuffer,
+     *   DWORD nSize,
+     *   va_list *Arguments
+     * )
+     */
+    static native String FormatMessage(int errorCode);
+
+    /**
+     * LocalFree(
+     *   HLOCAL hMem
+     * )
+     */
+    static native void LocalFree(long address);
+
+    /**
+     * HANDLE CreateIoCompletionPort (
+     *   HANDLE FileHandle,
+     *   HANDLE ExistingCompletionPort,
+     *   DWORD CompletionKey,
+     *   DWORD NumberOfConcurrentThreads
+     * )
+     */
+    static native long CreateIoCompletionPort(long fileHandle, long existingPort,
+        int completionKey) throws WindowsException;
+
+
+    /**
+     * GetQueuedCompletionStatus(
+     *   HANDLE CompletionPort,
+     *   LPDWORD lpNumberOfBytesTransferred,
+     *   LPDWORD lpCompletionKey,
+     *   LPOVERLAPPED *lpOverlapped,
+     *   DWORD dwMilliseconds
+     */
+    static CompletionStatus GetQueuedCompletionStatus(long completionPort)
+        throws WindowsException
+    {
+        CompletionStatus status = new CompletionStatus();
+        GetQueuedCompletionStatus0(completionPort, status);
+        return status;
+    }
+    static class CompletionStatus {
+        private int error;
+        private int bytesTransferred;
+        private int completionKey;
+        private CompletionStatus() { }
+
+        int error() { return error; }
+        int bytesTransferred() { return bytesTransferred; }
+        int completionKey() { return completionKey; }
+    }
+    private static native void GetQueuedCompletionStatus0(long completionPort,
+        CompletionStatus status) throws WindowsException;
+
+    /**
+     * PostQueuedCompletionStatus(
+     *   HANDLE CompletionPort,
+     *   DWORD dwNumberOfBytesTransferred,
+     *   DWORD dwCompletionKey,
+     *   LPOVERLAPPED lpOverlapped
+     * )
+     */
+    static native void PostQueuedCompletionStatus(long completionPort,
+        int completionKey) throws WindowsException;
+
+    /**
+     * ReadDirectoryChangesW(
+     *   HANDLE hDirectory,
+     *   LPVOID lpBuffer,
+     *   DWORD nBufferLength,
+     *   BOOL bWatchSubtree,
+     *   DWORD dwNotifyFilter,
+     *   LPDWORD lpBytesReturned,
+     *   LPOVERLAPPED lpOverlapped,
+     *   LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+     * )
+     */
+    static native void ReadDirectoryChangesW(long hDirectory,
+                                             long bufferAddress,
+                                             int bufferLength,
+                                             boolean watchSubTree,
+                                             int filter,
+                                             long bytesReturnedAddress,
+                                             long pOverlapped)
+        throws WindowsException;
+
+    /**
+     * BackupRead(
+     *   HANDLE hFile,
+     *   LPBYTE lpBuffer,
+     *   DWORD nNumberOfBytesToRead,
+     *   LPDWORD lpNumberOfBytesRead,
+     *   BOOL bAbort,
+     *   BOOL bProcessSecurity,
+     *   LPVOID* lpContext
+     * )
+     */
+    static BackupResult BackupRead(long hFile,
+                                   long bufferAddress,
+                                   int bufferSize,
+                                   boolean abort,
+                                   long context)
+        throws WindowsException
+    {
+        BackupResult result = new BackupResult();
+        BackupRead0(hFile, bufferAddress, bufferSize, abort, context, result);
+        return result;
+    }
+    static class BackupResult {
+        private int bytesTransferred;
+        private long context;
+        private BackupResult() { }
+
+        int bytesTransferred() { return bytesTransferred; }
+        long context() { return context; }
+    }
+    private static native void BackupRead0(long hFile, long bufferAddress,
+        int bufferSize, boolean abort, long context, BackupResult result)
+        throws WindowsException;
+
+    /**
+     * BackupSeek(
+     *   HANDLE hFile,
+     *   DWORD dwLowBytesToSeek,
+     *   DWORD dwHighBytesToSeek,
+     *   LPDWORD lpdwLowByteSeeked,
+     *   LPDWORD lpdwHighByteSeeked,
+     *   LPVOID* lpContext
+     * )
+     */
+    static native void BackupSeek(long hFile, long bytesToSeek, long context)
+        throws WindowsException;
+
+
+    // -- support for copying String with a NativeBuffer --
+
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    static NativeBuffer asNativeBuffer(String s) {
+        int stringLengthInBytes = s.length() << 1;
+        int sizeInBytes = stringLengthInBytes + 2;  // char terminator
+
+        // get a native buffer of sufficient size
+        NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(sizeInBytes);
+        if (buffer == null) {
+            buffer = NativeBuffers.allocNativeBuffer(sizeInBytes);
+        } else {
+            // buffer already contains the string contents
+            if (buffer.owner() == s)
+                return buffer;
+        }
+
+        // copy into buffer and zero terminate
+        char[] chars = s.toCharArray();
+        unsafe.copyMemory(chars, Unsafe.ARRAY_CHAR_BASE_OFFSET, null,
+            buffer.address(), (long)stringLengthInBytes);
+        unsafe.putChar(buffer.address() + stringLengthInBytes, (char)0);
+        buffer.setOwner(s);
+        return buffer;
+    }
+
+    // -- native library initialization --
+
+    private static native void initIDs();
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                // nio.dll has dependency on net.dll
+                System.loadLibrary("net");
+                System.loadLibrary("nio");
+                return null;
+        }});
+        initIDs();
+    }
+
+}