/*
 * Copyright (c) 2008, 2009, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.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 int attributes;

        private FirstFile() { }
        public long handle()    { return handle; }
        public String name()    { return name; }
        public int attributes() { return attributes; }
    }
    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 or null
     */
    static native String FindNextFile(long handle, long address)
        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();
    }

}
