mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
1198 lines
36 KiB
Java
1198 lines
36 KiB
Java
/*
|
|
* Copyright (c) 2008, 2022, 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.Blocker;
|
|
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
|
|
{
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
return CreateFile0(buffer.address(),
|
|
dwDesiredAccess,
|
|
dwShareMode,
|
|
lpSecurityAttributes,
|
|
dwCreationDisposition,
|
|
dwFlagsAndAttributes);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
}
|
|
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 {
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
DeleteFile0(buffer.address());
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
}
|
|
private static native void DeleteFile0(long lpFileName)
|
|
throws WindowsException;
|
|
|
|
/**
|
|
* CreateDirectory(
|
|
* LPCTSTR lpPathName,
|
|
* LPSECURITY_ATTRIBUTES lpSecurityAttributes
|
|
* )
|
|
*/
|
|
static void CreateDirectory(String path, long lpSecurityAttributes) throws WindowsException {
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
CreateDirectory0(buffer.address(), lpSecurityAttributes);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
}
|
|
private static native void CreateDirectory0(long lpFileName, long lpSecurityAttributes)
|
|
throws WindowsException;
|
|
|
|
/**
|
|
* RemoveDirectory(
|
|
* LPCTSTR lpPathName
|
|
* )
|
|
*/
|
|
static void RemoveDirectory(String path) throws WindowsException {
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
RemoveDirectory0(buffer.address());
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
}
|
|
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;
|
|
|
|
/**
|
|
* Retrieves the size of the specified file.
|
|
*
|
|
* BOOL GetFileSizeEx(
|
|
* HANDLE hFile,
|
|
* PLARGE_INTEGER lpFileSize
|
|
* )
|
|
*/
|
|
static native long GetFileSizeEx(long handle) throws WindowsException;
|
|
|
|
/**
|
|
* HANDLE FindFirstFile(
|
|
* LPCTSTR lpFileName,
|
|
* LPWIN32_FIND_DATA lpFindFileData
|
|
* )
|
|
*/
|
|
static FirstFile FindFirstFile(String path) throws WindowsException {
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
FirstFile data = new FirstFile();
|
|
long comp = Blocker.begin();
|
|
try {
|
|
FindFirstFile0(buffer.address(), data);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
return data;
|
|
}
|
|
}
|
|
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 {
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
return FindFirstFile1(buffer.address(), address);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
}
|
|
private static native long FindFirstFile1(long lpFileName, long address)
|
|
throws WindowsException;
|
|
|
|
/**
|
|
* FindNextFile(
|
|
* HANDLE hFindFile,
|
|
* LPWIN32_FIND_DATA lpFindFileData
|
|
* )
|
|
*
|
|
* @return lpFindFileData->cFileName or null
|
|
*/
|
|
static String FindNextFile(long handle, long address) throws WindowsException {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
return FindNextFile0(handle, address);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
private static native String FindNextFile0(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 {
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
FirstStream data = new FirstStream();
|
|
long comp = Blocker.begin();
|
|
try {
|
|
FindFirstStream0(buffer.address(), data);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
if (data.handle() == WindowsConstants.INVALID_HANDLE_VALUE)
|
|
return null;
|
|
return data;
|
|
}
|
|
}
|
|
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 String FindNextStream(long handle) throws WindowsException {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
return FindNextStream0(handle);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
private static native String FindNextStream0(long handle) throws WindowsException;
|
|
|
|
/**
|
|
* FindClose(
|
|
* HANDLE hFindFile
|
|
* )
|
|
*/
|
|
static native void FindClose(long handle) throws WindowsException;
|
|
|
|
/**
|
|
* GetFileInformationByHandle(
|
|
* HANDLE hFile,
|
|
* LPBY_HANDLE_FILE_INFORMATION lpFileInformation
|
|
* )
|
|
*/
|
|
static void GetFileInformationByHandle(long handle, long address)
|
|
throws WindowsException
|
|
{
|
|
long comp = Blocker.begin();
|
|
try {
|
|
GetFileInformationByHandle0(handle, address);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
private static native void GetFileInformationByHandle0(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
|
|
{
|
|
try (NativeBuffer sourceBuffer = asNativeBuffer(source);
|
|
NativeBuffer targetBuffer = asNativeBuffer(target)) {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
CopyFileEx0(sourceBuffer.address(), targetBuffer.address(), flags,
|
|
addressToPollForCancel);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
}
|
|
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
|
|
{
|
|
try (NativeBuffer sourceBuffer = asNativeBuffer(source);
|
|
NativeBuffer targetBuffer = asNativeBuffer(target)) {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
MoveFileEx0(sourceBuffer.address(), targetBuffer.address(), flags);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
}
|
|
private static native void MoveFileEx0(long existingAddress, long newAddress,
|
|
int flags) throws WindowsException;
|
|
|
|
/**
|
|
* DWORD GetFileAttributes(
|
|
* LPCTSTR lpFileName
|
|
* )
|
|
*/
|
|
static int GetFileAttributes(String path) throws WindowsException {
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
return GetFileAttributes0(buffer.address());
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
}
|
|
private static native int GetFileAttributes0(long lpFileName)
|
|
throws WindowsException;
|
|
|
|
/**
|
|
* SetFileAttributes(
|
|
* LPCTSTR lpFileName,
|
|
* DWORD dwFileAttributes
|
|
*/
|
|
static void SetFileAttributes(String path, int dwFileAttributes)
|
|
throws WindowsException
|
|
{
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
SetFileAttributes0(buffer.address(), dwFileAttributes);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
}
|
|
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 {
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
long comp = Blocker.begin();
|
|
try {
|
|
GetFileAttributesEx0(buffer.address(), address);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
}
|
|
private static native void GetFileAttributesEx0(long lpFileName, long address)
|
|
throws WindowsException;
|
|
|
|
/**
|
|
* SetFileTime(
|
|
* HANDLE hFile,
|
|
* CONST FILETIME *lpCreationTime,
|
|
* CONST FILETIME *lpLastAccessTime,
|
|
* CONST FILETIME *lpLastWriteTime
|
|
* )
|
|
*/
|
|
static void SetFileTime(long handle, long createTime, long lastAccessTime, long lastWriteTime)
|
|
throws WindowsException
|
|
{
|
|
long comp = Blocker.begin();
|
|
try {
|
|
SetFileTime0(handle, createTime, lastAccessTime, lastWriteTime);
|
|
} finally {
|
|
Blocker.end(comp);
|
|
}
|
|
}
|
|
private static native void SetFileTime0(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
|
|
{
|
|
try (NativeBuffer buffer = asNativeBuffer(root)) {
|
|
VolumeInformation info = new VolumeInformation();
|
|
GetVolumeInformation0(buffer.address(), info);
|
|
return info;
|
|
}
|
|
}
|
|
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 {
|
|
try (NativeBuffer buffer = asNativeBuffer(root)) {
|
|
return GetDriveType0(buffer.address());
|
|
}
|
|
}
|
|
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
|
|
{
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
DiskFreeSpace space = new DiskFreeSpace();
|
|
GetDiskFreeSpaceEx0(buffer.address(), space);
|
|
return space;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* GetDiskFreeSpace(
|
|
* LPCTSTR lpRootPathName,
|
|
* LPDWORD lpSectorsPerCluster,
|
|
* LPDWORD lpBytesPerSector,
|
|
* LPDWORD lpNumberOfFreeClusters,
|
|
* LPDWORD lpTotalNumberOfClusters
|
|
* )
|
|
*/
|
|
static DiskFreeSpace GetDiskFreeSpace(String path)
|
|
throws WindowsException
|
|
{
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
DiskFreeSpace space = new DiskFreeSpace();
|
|
GetDiskFreeSpace0(buffer.address(), space);
|
|
return space;
|
|
}
|
|
}
|
|
|
|
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 {
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
return GetVolumePathName0(buffer.address());
|
|
}
|
|
}
|
|
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
|
|
{
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
return GetFileSecurity0(buffer.address(), requestedInformation,
|
|
pSecurityDescriptor, nLength);
|
|
}
|
|
}
|
|
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
|
|
{
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
// may be called with elevated privileges so always run on current thread
|
|
SetFileSecurity0(buffer.address(), securityInformation, pSecurityDescriptor);
|
|
}
|
|
}
|
|
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
|
|
{
|
|
try (NativeBuffer buffer = asNativeBuffer(accountName)) {
|
|
return LookupAccountName0(buffer.address(), pSid, cbSid);
|
|
}
|
|
}
|
|
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
|
|
{
|
|
try (NativeBuffer buffer = asNativeBuffer(sidString)) {
|
|
return ConvertStringSidToSid0(buffer.address());
|
|
}
|
|
}
|
|
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 {
|
|
try (NativeBuffer buffer = asNativeBuffer(name)) {
|
|
return LookupPrivilegeValue0(buffer.address());
|
|
}
|
|
}
|
|
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
|
|
{
|
|
try (NativeBuffer newFileBuffer = asNativeBuffer(newFile);
|
|
NativeBuffer existingFileBuffer = asNativeBuffer(existingFile)) {
|
|
CreateHardLink0(newFileBuffer.address(), existingFileBuffer.address());
|
|
}
|
|
}
|
|
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 {
|
|
try (NativeBuffer buffer = asNativeBuffer(path)) {
|
|
return GetFullPathName0(buffer.address());
|
|
}
|
|
}
|
|
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)
|
|
throws WindowsException
|
|
{
|
|
CompletionStatus status = new CompletionStatus();
|
|
GetQueuedCompletionStatus0(completionPort, status);
|
|
return status;
|
|
}
|
|
static class CompletionStatus {
|
|
private int error;
|
|
private int bytesTransferred;
|
|
private long completionKey;
|
|
private CompletionStatus() { }
|
|
|
|
int error() { return error; }
|
|
int bytesTransferred() { return bytesTransferred; }
|
|
long completionKey() { return completionKey; }
|
|
}
|
|
private static native void GetQueuedCompletionStatus0(long completionPort,
|
|
CompletionStatus status) throws WindowsException;
|
|
|
|
/**
|
|
* PostQueuedCompletionStatus(
|
|
* HANDLE CompletionPort,
|
|
* DWORD dwNumberOfBytesTransferred,
|
|
* ULONG_PTR dwCompletionKey,
|
|
* LPOVERLAPPED lpOverlapped
|
|
* )
|
|
*/
|
|
static native void PostQueuedCompletionStatus(long completionPort,
|
|
long 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;
|
|
|
|
|
|
/**
|
|
* CancelIo(
|
|
* HANDLE hFile
|
|
* )
|
|
*/
|
|
static native void CancelIo(long hFile) throws WindowsException;
|
|
|
|
/**
|
|
* GetOverlappedResult(
|
|
* HANDLE hFile,
|
|
* LPOVERLAPPED lpOverlapped,
|
|
* LPDWORD lpNumberOfBytesTransferred,
|
|
* BOOL bWait
|
|
* );
|
|
*/
|
|
static native int GetOverlappedResult(long hFile, long lpOverlapped)
|
|
throws WindowsException;
|
|
|
|
// -- support for copying String with a NativeBuffer --
|
|
|
|
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
|
|
|
static NativeBuffer asNativeBuffer(String s) throws WindowsException {
|
|
if (s.length() > (Integer.MAX_VALUE - 2)/2) {
|
|
throw new WindowsException
|
|
("String too long to convert to native buffer");
|
|
}
|
|
|
|
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 {
|
|
// nio.dll has dependency on net.dll
|
|
jdk.internal.loader.BootLoader.loadLibrary("net");
|
|
jdk.internal.loader.BootLoader.loadLibrary("nio");
|
|
initIDs();
|
|
}
|
|
|
|
}
|