/*
* Copyright (c) 2008, 2019, 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 jdk.internal.misc.Unsafe;
import static sun.nio.fs.WindowsConstants.*;
/**
* Win32 and library calls.
*/
class WindowsNativeDispatcher {
private WindowsNativeDispatcher() { }
/**
* HANDLE CreateEvent(
* LPSECURITY_ATTRIBUTES lpEventAttributes,
* BOOL bManualReset,
* BOOL bInitialState,
* PCTSTR lpName
* );
*/
static native long CreateEvent(boolean bManualReset, boolean bInitialState)
throws WindowsException;
/**
* 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();
}
}
/**
* GetDiskFreeSpace(
* LPCTSTR lpRootPathName,
* LPDWORD lpSectorsPerCluster,
* LPDWORD lpBytesPerSector,
* LPDWORD lpNumberOfFreeClusters,
* LPDWORD lpTotalNumberOfClusters
* )
*/
static DiskFreeSpace GetDiskFreeSpace(String path)
throws WindowsException
{
NativeBuffer buffer = asNativeBuffer(path);
try {
DiskFreeSpace space = new DiskFreeSpace();
GetDiskFreeSpace0(buffer.address(), space);
return space;
} finally {
buffer.release();
}
}
static class DiskFreeSpace {
private long freeBytesAvailable;
private long totalNumberOfBytes;
private long totalNumberOfFreeBytes;
private long bytesPerSector;
private DiskFreeSpace() { }
public long freeBytesAvailable() { return freeBytesAvailable; }
public long totalNumberOfBytes() { return totalNumberOfBytes; }
public long totalNumberOfFreeBytes() { return totalNumberOfFreeBytes; }
public long bytesPerSector() { return bytesPerSector; }
}
private static native void GetDiskFreeSpaceEx0(long lpDirectoryName,
DiskFreeSpace obj)
throws WindowsException;
private static native void GetDiskFreeSpace0(long lpRootPathName,
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;
/**
* AccessCheck(
* PSECURITY_DESCRIPTOR pSecurityDescriptor,
* HANDLE ClientToken,
* DWORD DesiredAccess,
* PGENERIC_MAPPING GenericMapping,
* PPRIVILEGE_SET PrivilegeSet,
* LPDWORD PrivilegeSetLength,
* LPDWORD GrantedAccess,
* LPBOOL AccessStatus
* )
*/
static native boolean AccessCheck(long token, long securityInfo, int accessMask,
int genericRead, int genericWrite, int genericExecute, int genericAll)
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;
/**
* CreateSymbolicLink(
* LPCWSTR lpSymlinkFileName,
* LPCWSTR lpTargetFileName,
* DWORD dwFlags
* )
*
* Creates a symbolic link, conditionally retrying with the addition of
* the flag SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE if the initial
* attempt fails with ERROR_PRIVILEGE_NOT_HELD. If the retry fails, throw
* the original exception due to ERROR_PRIVILEGE_NOT_HELD. The retry will
* succeed only on Windows build 14972 or later if Developer Mode is on.
*/
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);
} catch (WindowsException x) {
if (x.lastError() == ERROR_PRIVILEGE_NOT_HELD) {
flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
try {
CreateSymbolicLink0(linkBuffer.address(),
targetBuffer.address(), flags);
return;
} catch (WindowsException ignored) {
// Will fail with ERROR_INVALID_PARAMETER for Windows
// builds older than 14972.
}
}
throw x;
} 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 existingFileBuffer) 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,
* ULONG_PTR CompletionKey,
* DWORD NumberOfConcurrentThreads
* )
*/
static native long CreateIoCompletionPort(long fileHandle, long existingPort,
long completionKey) throws WindowsException;
/**
* GetQueuedCompletionStatus(
* HANDLE CompletionPort,
* LPDWORD lpNumberOfBytesTransferred,
* PULONG_PTR lpCompletionKey,
* LPOVERLAPPED *lpOverlapped,
* DWORD dwMilliseconds
*/
static CompletionStatus GetQueuedCompletionStatus(long completionPort)
/**代码未完, 请加载全部代码(NowJava.com).**/