diff -r 115e09b7a004 -r 3acf8e5e2ca0 jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java --- /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() { + public Void run() { + // nio.dll has dependency on net.dll + System.loadLibrary("net"); + System.loadLibrary("nio"); + return null; + }}); + initIDs(); + } + +}