Path: blob/master/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java
41139 views
/*1* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.fs;2627import jdk.internal.misc.Unsafe;2829import static sun.nio.fs.WindowsConstants.*;3031/**32* Win32 and library calls.33*/3435class WindowsNativeDispatcher {36private WindowsNativeDispatcher() { }3738/**39* HANDLE CreateEvent(40* LPSECURITY_ATTRIBUTES lpEventAttributes,41* BOOL bManualReset,42* BOOL bInitialState,43* PCTSTR lpName44* );45*/46static native long CreateEvent(boolean bManualReset, boolean bInitialState)47throws WindowsException;4849/**50* HANDLE CreateFile(51* LPCTSTR lpFileName,52* DWORD dwDesiredAccess,53* DWORD dwShareMode,54* LPSECURITY_ATTRIBUTES lpSecurityAttributes,55* DWORD dwCreationDisposition,56* DWORD dwFlagsAndAttributes,57* HANDLE hTemplateFile58* )59*/60static long CreateFile(String path,61int dwDesiredAccess,62int dwShareMode,63long lpSecurityAttributes,64int dwCreationDisposition,65int dwFlagsAndAttributes)66throws WindowsException67{68NativeBuffer buffer = asNativeBuffer(path);69try {70return CreateFile0(buffer.address(),71dwDesiredAccess,72dwShareMode,73lpSecurityAttributes,74dwCreationDisposition,75dwFlagsAndAttributes);76} finally {77buffer.release();78}79}80static long CreateFile(String path,81int dwDesiredAccess,82int dwShareMode,83int dwCreationDisposition,84int dwFlagsAndAttributes)85throws WindowsException86{87return CreateFile(path, dwDesiredAccess, dwShareMode, 0L,88dwCreationDisposition, dwFlagsAndAttributes);89}90private static native long CreateFile0(long lpFileName,91int dwDesiredAccess,92int dwShareMode,93long lpSecurityAttributes,94int dwCreationDisposition,95int dwFlagsAndAttributes)96throws WindowsException;9798/**99* CloseHandle(100* HANDLE hObject101* )102*/103static native void CloseHandle(long handle);104105/**106* DeleteFile(107* LPCTSTR lpFileName108* )109*/110static void DeleteFile(String path) throws WindowsException {111NativeBuffer buffer = asNativeBuffer(path);112try {113DeleteFile0(buffer.address());114} finally {115buffer.release();116}117}118private static native void DeleteFile0(long lpFileName)119throws WindowsException;120121/**122* CreateDirectory(123* LPCTSTR lpPathName,124* LPSECURITY_ATTRIBUTES lpSecurityAttributes125* )126*/127static void CreateDirectory(String path, long lpSecurityAttributes) throws WindowsException {128NativeBuffer buffer = asNativeBuffer(path);129try {130CreateDirectory0(buffer.address(), lpSecurityAttributes);131} finally {132buffer.release();133}134}135private static native void CreateDirectory0(long lpFileName, long lpSecurityAttributes)136throws WindowsException;137138/**139* RemoveDirectory(140* LPCTSTR lpPathName141* )142*/143static void RemoveDirectory(String path) throws WindowsException {144NativeBuffer buffer = asNativeBuffer(path);145try {146RemoveDirectory0(buffer.address());147} finally {148buffer.release();149}150}151private static native void RemoveDirectory0(long lpFileName)152throws WindowsException;153154/**155* Marks a file as a sparse file.156*157* DeviceIoControl(158* FSCTL_SET_SPARSE159* )160*/161static native void DeviceIoControlSetSparse(long handle)162throws WindowsException;163164/**165* Retrieves the reparse point data associated with the file or directory.166*167* DeviceIoControl(168* FSCTL_GET_REPARSE_POINT169* )170*/171static native void DeviceIoControlGetReparsePoint(long handle,172long bufferAddress, int bufferSize) throws WindowsException;173174/**175* Retrieves the size of the specified file.176*177* BOOL GetFileSizeEx(178* HANDLE hFile,179* PLARGE_INTEGER lpFileSize180* )181*/182static native long GetFileSizeEx(long handle) throws WindowsException;183184/**185* HANDLE FindFirstFile(186* LPCTSTR lpFileName,187* LPWIN32_FIND_DATA lpFindFileData188* )189*/190static FirstFile FindFirstFile(String path) throws WindowsException {191NativeBuffer buffer = asNativeBuffer(path);192try {193FirstFile data = new FirstFile();194FindFirstFile0(buffer.address(), data);195return data;196} finally {197buffer.release();198}199}200static class FirstFile {201private long handle;202private String name;203private int attributes;204205private FirstFile() { }206public long handle() { return handle; }207public String name() { return name; }208public int attributes() { return attributes; }209}210private static native void FindFirstFile0(long lpFileName, FirstFile obj)211throws WindowsException;212213/**214* HANDLE FindFirstFile(215* LPCTSTR lpFileName,216* LPWIN32_FIND_DATA lpFindFileData217* )218*/219static long FindFirstFile(String path, long address) throws WindowsException {220NativeBuffer buffer = asNativeBuffer(path);221try {222return FindFirstFile1(buffer.address(), address);223} finally {224buffer.release();225}226}227private static native long FindFirstFile1(long lpFileName, long address)228throws WindowsException;229230/**231* FindNextFile(232* HANDLE hFindFile,233* LPWIN32_FIND_DATA lpFindFileData234* )235*236* @return lpFindFileData->cFileName or null237*/238static native String FindNextFile(long handle, long address)239throws WindowsException;240241/**242* HANDLE FindFirstStreamW(243* LPCWSTR lpFileName,244* STREAM_INFO_LEVELS InfoLevel,245* LPVOID lpFindStreamData,246* DWORD dwFlags247* )248*/249static FirstStream FindFirstStream(String path) throws WindowsException {250NativeBuffer buffer = asNativeBuffer(path);251try {252FirstStream data = new FirstStream();253FindFirstStream0(buffer.address(), data);254if (data.handle() == WindowsConstants.INVALID_HANDLE_VALUE)255return null;256return data;257} finally {258buffer.release();259}260}261static class FirstStream {262private long handle;263private String name;264265private FirstStream() { }266public long handle() { return handle; }267public String name() { return name; }268}269private static native void FindFirstStream0(long lpFileName, FirstStream obj)270throws WindowsException;271272/*273* FindNextStreamW(274* HANDLE hFindStream,275* LPVOID lpFindStreamData276* )277*/278static native String FindNextStream(long handle) throws WindowsException;279280/**281* FindClose(282* HANDLE hFindFile283* )284*/285static native void FindClose(long handle) throws WindowsException;286287/**288* GetFileInformationByHandle(289* HANDLE hFile,290* LPBY_HANDLE_FILE_INFORMATION lpFileInformation291* )292*/293static native void GetFileInformationByHandle(long handle, long address)294throws WindowsException;295296/**297* CopyFileEx(298* LPCWSTR lpExistingFileName299* LPCWSTR lpNewFileName,300* LPPROGRESS_ROUTINE lpProgressRoutine301* LPVOID lpData,302* LPBOOL pbCancel,303* DWORD dwCopyFlags304* )305*/306static void CopyFileEx(String source, String target, int flags,307long addressToPollForCancel)308throws WindowsException309{310NativeBuffer sourceBuffer = asNativeBuffer(source);311NativeBuffer targetBuffer = asNativeBuffer(target);312try {313CopyFileEx0(sourceBuffer.address(), targetBuffer.address(), flags,314addressToPollForCancel);315} finally {316targetBuffer.release();317sourceBuffer.release();318}319}320private static native void CopyFileEx0(long existingAddress, long newAddress,321int flags, long addressToPollForCancel) throws WindowsException;322323/**324* MoveFileEx(325* LPCTSTR lpExistingFileName,326* LPCTSTR lpNewFileName,327* DWORD dwFlags328* )329*/330static void MoveFileEx(String source, String target, int flags)331throws WindowsException332{333NativeBuffer sourceBuffer = asNativeBuffer(source);334NativeBuffer targetBuffer = asNativeBuffer(target);335try {336MoveFileEx0(sourceBuffer.address(), targetBuffer.address(), flags);337} finally {338targetBuffer.release();339sourceBuffer.release();340}341}342private static native void MoveFileEx0(long existingAddress, long newAddress,343int flags) throws WindowsException;344345/**346* DWORD GetFileAttributes(347* LPCTSTR lpFileName348* )349*/350static int GetFileAttributes(String path) throws WindowsException {351NativeBuffer buffer = asNativeBuffer(path);352try {353return GetFileAttributes0(buffer.address());354} finally {355buffer.release();356}357}358private static native int GetFileAttributes0(long lpFileName)359throws WindowsException;360361/**362* SetFileAttributes(363* LPCTSTR lpFileName,364* DWORD dwFileAttributes365*/366static void SetFileAttributes(String path, int dwFileAttributes)367throws WindowsException368{369NativeBuffer buffer = asNativeBuffer(path);370try {371SetFileAttributes0(buffer.address(), dwFileAttributes);372} finally {373buffer.release();374}375}376private static native void SetFileAttributes0(long lpFileName,377int dwFileAttributes) throws WindowsException;378379/**380* GetFileAttributesEx(381* LPCTSTR lpFileName,382* GET_FILEEX_INFO_LEVELS fInfoLevelId,383* LPVOID lpFileInformation384* );385*/386static void GetFileAttributesEx(String path, long address) throws WindowsException {387NativeBuffer buffer = asNativeBuffer(path);388try {389GetFileAttributesEx0(buffer.address(), address);390} finally {391buffer.release();392}393}394private static native void GetFileAttributesEx0(long lpFileName, long address)395throws WindowsException;396/**397* SetFileTime(398* HANDLE hFile,399* CONST FILETIME *lpCreationTime,400* CONST FILETIME *lpLastAccessTime,401* CONST FILETIME *lpLastWriteTime402* )403*/404static native void SetFileTime(long handle,405long createTime,406long lastAccessTime,407long lastWriteTime)408throws WindowsException;409410/**411* SetEndOfFile(412* HANDLE hFile413* )414*/415static native void SetEndOfFile(long handle) throws WindowsException;416417/**418* DWORD GetLogicalDrives(VOID)419*/420static native int GetLogicalDrives() throws WindowsException;421422/**423* GetVolumeInformation(424* LPCTSTR lpRootPathName,425* LPTSTR lpVolumeNameBuffer,426* DWORD nVolumeNameSize,427* LPDWORD lpVolumeSerialNumber,428* LPDWORD lpMaximumComponentLength,429* LPDWORD lpFileSystemFlags,430* LPTSTR lpFileSystemNameBuffer,431* DWORD nFileSystemNameSize432* )433*/434static VolumeInformation GetVolumeInformation(String root)435throws WindowsException436{437NativeBuffer buffer = asNativeBuffer(root);438try {439VolumeInformation info = new VolumeInformation();440GetVolumeInformation0(buffer.address(), info);441return info;442} finally {443buffer.release();444}445}446static class VolumeInformation {447private String fileSystemName;448private String volumeName;449private int volumeSerialNumber;450private int flags;451private VolumeInformation() { }452453public String fileSystemName() { return fileSystemName; }454public String volumeName() { return volumeName; }455public int volumeSerialNumber() { return volumeSerialNumber; }456public int flags() { return flags; }457}458private static native void GetVolumeInformation0(long lpRoot,459VolumeInformation obj)460throws WindowsException;461462/**463* UINT GetDriveType(464* LPCTSTR lpRootPathName465* )466*/467static int GetDriveType(String root) throws WindowsException {468NativeBuffer buffer = asNativeBuffer(root);469try {470return GetDriveType0(buffer.address());471} finally {472buffer.release();473}474}475private static native int GetDriveType0(long lpRoot) throws WindowsException;476477/**478* GetDiskFreeSpaceEx(479* LPCTSTR lpDirectoryName,480* PULARGE_INTEGER lpFreeBytesAvailableToCaller,481* PULARGE_INTEGER lpTotalNumberOfBytes,482* PULARGE_INTEGER lpTotalNumberOfFreeBytes483* )484*/485static DiskFreeSpace GetDiskFreeSpaceEx(String path)486throws WindowsException487{488NativeBuffer buffer = asNativeBuffer(path);489try {490DiskFreeSpace space = new DiskFreeSpace();491GetDiskFreeSpaceEx0(buffer.address(), space);492return space;493} finally {494buffer.release();495}496}497498/**499* GetDiskFreeSpace(500* LPCTSTR lpRootPathName,501* LPDWORD lpSectorsPerCluster,502* LPDWORD lpBytesPerSector,503* LPDWORD lpNumberOfFreeClusters,504* LPDWORD lpTotalNumberOfClusters505* )506*/507static DiskFreeSpace GetDiskFreeSpace(String path)508throws WindowsException509{510NativeBuffer buffer = asNativeBuffer(path);511try {512DiskFreeSpace space = new DiskFreeSpace();513GetDiskFreeSpace0(buffer.address(), space);514return space;515} finally {516buffer.release();517}518}519520static class DiskFreeSpace {521private long freeBytesAvailable;522private long totalNumberOfBytes;523private long totalNumberOfFreeBytes;524private long bytesPerSector;525private DiskFreeSpace() { }526527public long freeBytesAvailable() { return freeBytesAvailable; }528public long totalNumberOfBytes() { return totalNumberOfBytes; }529public long totalNumberOfFreeBytes() { return totalNumberOfFreeBytes; }530public long bytesPerSector() { return bytesPerSector; }531}532private static native void GetDiskFreeSpaceEx0(long lpDirectoryName,533DiskFreeSpace obj)534throws WindowsException;535536537private static native void GetDiskFreeSpace0(long lpRootPathName,538DiskFreeSpace obj)539throws WindowsException;540541/**542* GetVolumePathName(543* LPCTSTR lpszFileName,544* LPTSTR lpszVolumePathName,545* DWORD cchBufferLength546* )547*548* @return lpFileName549*/550static String GetVolumePathName(String path) throws WindowsException {551NativeBuffer buffer = asNativeBuffer(path);552try {553return GetVolumePathName0(buffer.address());554} finally {555buffer.release();556}557}558private static native String GetVolumePathName0(long lpFileName)559throws WindowsException;560561562/**563* InitializeSecurityDescriptor(564* PSECURITY_DESCRIPTOR pSecurityDescriptor,565* DWORD dwRevision566* )567*/568static native void InitializeSecurityDescriptor(long sdAddress)569throws WindowsException;570571/**572* InitializeAcl(573* PACL pAcl,574* DWORD nAclLength,575* DWORD dwAclRevision576* )577*/578static native void InitializeAcl(long aclAddress, int size)579throws WindowsException;580581/**582* GetFileSecurity(583* LPCTSTR lpFileName,584* SECURITY_INFORMATION RequestedInformation,585* PSECURITY_DESCRIPTOR pSecurityDescriptor,586* DWORD nLength,587* LPDWORD lpnLengthNeeded588* )589*/590static int GetFileSecurity(String path,591int requestedInformation,592long pSecurityDescriptor,593int nLength) throws WindowsException594{595NativeBuffer buffer = asNativeBuffer(path);596try {597return GetFileSecurity0(buffer.address(), requestedInformation,598pSecurityDescriptor, nLength);599} finally {600buffer.release();601}602}603private static native int GetFileSecurity0(long lpFileName,604int requestedInformation,605long pSecurityDescriptor,606int nLength) throws WindowsException;607608/**609* SetFileSecurity(610* LPCTSTR lpFileName,611* SECURITY_INFORMATION SecurityInformation,612* PSECURITY_DESCRIPTOR pSecurityDescriptor613* )614*/615static void SetFileSecurity(String path,616int securityInformation,617long pSecurityDescriptor)618throws WindowsException619{620NativeBuffer buffer = asNativeBuffer(path);621try {622SetFileSecurity0(buffer.address(), securityInformation,623pSecurityDescriptor);624} finally {625buffer.release();626}627}628static native void SetFileSecurity0(long lpFileName, int securityInformation,629long pSecurityDescriptor) throws WindowsException;630631/**632* GetSecurityDescriptorOwner(633* PSECURITY_DESCRIPTOR pSecurityDescriptor634* PSID *pOwner,635* LPBOOL lpbOwnerDefaulted636* )637*638* @return pOwner639*/640static native long GetSecurityDescriptorOwner(long pSecurityDescriptor)641throws WindowsException;642643/**644* SetSecurityDescriptorOwner(645* PSECURITY_DESCRIPTOR pSecurityDescriptor,646* PSID pOwner,647* BOOL bOwnerDefaulted648* )649*/650static native void SetSecurityDescriptorOwner(long pSecurityDescriptor,651long pOwner)652throws WindowsException;653654/**655* GetSecurityDescriptorDacl(656* PSECURITY_DESCRIPTOR pSecurityDescriptor,657* LPBOOL lpbDaclPresent,658* PACL *pDacl,659* LPBOOL lpbDaclDefaulted660* )661*/662static native long GetSecurityDescriptorDacl(long pSecurityDescriptor);663664/**665* SetSecurityDescriptorDacl(666* PSECURITY_DESCRIPTOR pSecurityDescriptor,667* BOOL bDaclPresent,668* PACL pDacl,669* BOOL bDaclDefaulted670* )671*/672static native void SetSecurityDescriptorDacl(long pSecurityDescriptor, long pAcl)673throws WindowsException;674675676/**677* GetAclInformation(678* PACL pAcl,679* LPVOID pAclInformation,680* DWORD nAclInformationLength,681* ACL_INFORMATION_CLASS dwAclInformationClass682* )683*/684static AclInformation GetAclInformation(long aclAddress) {685AclInformation info = new AclInformation();686GetAclInformation0(aclAddress, info);687return info;688}689static class AclInformation {690private int aceCount;691private AclInformation() { }692693public int aceCount() { return aceCount; }694}695private static native void GetAclInformation0(long aclAddress,696AclInformation obj);697698/**699* GetAce(700* PACL pAcl,701* DWORD dwAceIndex,702* LPVOID *pAce703* )704*/705static native long GetAce(long aclAddress, int aceIndex);706707/**708* AddAccessAllowedAceEx(709* PACL pAcl,710* DWORD dwAceRevision,711* DWORD AceFlags,712* DWORD AccessMask,713* PSID pSid714* )715*/716static native void AddAccessAllowedAceEx(long aclAddress, int flags,717int mask, long sidAddress) throws WindowsException;718719/**720* AddAccessDeniedAceEx(721* PACL pAcl,722* DWORD dwAceRevision,723* DWORD AceFlags,724* DWORD AccessMask,725* PSID pSid726* )727*/728static native void AddAccessDeniedAceEx(long aclAddress, int flags,729int mask, long sidAddress) throws WindowsException;730731/**732* LookupAccountSid(733* LPCTSTR lpSystemName,734* PSID Sid,735* LPTSTR Name,736* LPDWORD cbName,737* LPTSTR ReferencedDomainName,738* LPDWORD cbReferencedDomainName,739* PSID_NAME_USE peUse740* )741*/742static Account LookupAccountSid(long sidAddress) throws WindowsException {743Account acc = new Account();744LookupAccountSid0(sidAddress, acc);745return acc;746}747static class Account {748private String domain;749private String name;750private int use;751private Account() { }752753public String domain() { return domain; }754public String name() { return name; }755public int use() { return use; }756}757private static native void LookupAccountSid0(long sidAddress, Account obj)758throws WindowsException;759760/**761* LookupAccountName(762* LPCTSTR lpSystemName,763* LPCTSTR lpAccountName,764* PSID Sid,765* LPDWORD cbSid,766* LPTSTR ReferencedDomainName,767* LPDWORD cbReferencedDomainName,768* PSID_NAME_USE peUse769* )770*771* @return cbSid772*/773static int LookupAccountName(String accountName,774long pSid,775int cbSid) throws WindowsException776{777NativeBuffer buffer = asNativeBuffer(accountName);778try {779return LookupAccountName0(buffer.address(), pSid, cbSid);780} finally {781buffer.release();782}783}784private static native int LookupAccountName0(long lpAccountName, long pSid,785int cbSid) throws WindowsException;786787/**788* DWORD GetLengthSid(789* PSID pSid790* )791*/792static native int GetLengthSid(long sidAddress);793794/**795* ConvertSidToStringSid(796* PSID Sid,797* LPTSTR* StringSid798* )799*800* @return StringSid801*/802static native String ConvertSidToStringSid(long sidAddress)803throws WindowsException;804805/**806* ConvertStringSidToSid(807* LPCTSTR StringSid,808* PSID* pSid809* )810*811* @return pSid812*/813static long ConvertStringSidToSid(String sidString)814throws WindowsException815{816NativeBuffer buffer = asNativeBuffer(sidString);817try {818return ConvertStringSidToSid0(buffer.address());819} finally {820buffer.release();821}822}823private static native long ConvertStringSidToSid0(long lpStringSid)824throws WindowsException;825826/**827* HANDLE GetCurrentProcess(VOID)828*/829static native long GetCurrentProcess();830831/**832* HANDLE GetCurrentThread(VOID)833*/834static native long GetCurrentThread();835836/**837* OpenProcessToken(838* HANDLE ProcessHandle,839* DWORD DesiredAccess,840* PHANDLE TokenHandle841* )842*/843static native long OpenProcessToken(long hProcess, int desiredAccess)844throws WindowsException;845846/**847* OpenThreadToken(848* HANDLE ThreadHandle,849* DWORD DesiredAccess,850* BOOL OpenAsSelf,851* PHANDLE TokenHandle852* )853*/854static native long OpenThreadToken(long hThread, int desiredAccess,855boolean openAsSelf) throws WindowsException;856857/**858*/859static native long DuplicateTokenEx(long hThread, int desiredAccess)860throws WindowsException;861862/**863* SetThreadToken(864* PHANDLE Thread,865* HANDLE Token866* )867*/868static native void SetThreadToken(long thread, long hToken)869throws WindowsException;870871/**872* GetTokenInformation(873* HANDLE TokenHandle,874* TOKEN_INFORMATION_CLASS TokenInformationClass,875* LPVOID TokenInformation,876* DWORD TokenInformationLength,877* PDWORD ReturnLength878* )879*/880static native int GetTokenInformation(long token, int tokenInfoClass,881long pTokenInfo, int tokenInfoLength) throws WindowsException;882883/**884* AdjustTokenPrivileges(885* HANDLE TokenHandle,886* BOOL DisableAllPrivileges887* PTOKEN_PRIVILEGES NewState888* DWORD BufferLength889* PTOKEN_PRIVILEGES890* PDWORD ReturnLength891* )892*/893static native void AdjustTokenPrivileges(long token, long luid, int attributes)894throws WindowsException;895896897/**898* AccessCheck(899* PSECURITY_DESCRIPTOR pSecurityDescriptor,900* HANDLE ClientToken,901* DWORD DesiredAccess,902* PGENERIC_MAPPING GenericMapping,903* PPRIVILEGE_SET PrivilegeSet,904* LPDWORD PrivilegeSetLength,905* LPDWORD GrantedAccess,906* LPBOOL AccessStatus907* )908*/909static native boolean AccessCheck(long token, long securityInfo, int accessMask,910int genericRead, int genericWrite, int genericExecute, int genericAll)911throws WindowsException;912913/**914*/915static long LookupPrivilegeValue(String name) throws WindowsException {916NativeBuffer buffer = asNativeBuffer(name);917try {918return LookupPrivilegeValue0(buffer.address());919} finally {920buffer.release();921}922}923private static native long LookupPrivilegeValue0(long lpName)924throws WindowsException;925926/**927* CreateSymbolicLink(928* LPCWSTR lpSymlinkFileName,929* LPCWSTR lpTargetFileName,930* DWORD dwFlags931* )932*933* Creates a symbolic link, conditionally retrying with the addition of934* the flag SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE if the initial935* attempt fails with ERROR_PRIVILEGE_NOT_HELD. If the retry fails, throw936* the original exception due to ERROR_PRIVILEGE_NOT_HELD. The retry will937* succeed only on Windows build 14972 or later if Developer Mode is on.938*/939static void CreateSymbolicLink(String link, String target, int flags)940throws WindowsException941{942NativeBuffer linkBuffer = asNativeBuffer(link);943NativeBuffer targetBuffer = asNativeBuffer(target);944try {945CreateSymbolicLink0(linkBuffer.address(), targetBuffer.address(),946flags);947} catch (WindowsException x) {948if (x.lastError() == ERROR_PRIVILEGE_NOT_HELD) {949flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;950try {951CreateSymbolicLink0(linkBuffer.address(),952targetBuffer.address(), flags);953return;954} catch (WindowsException ignored) {955// Will fail with ERROR_INVALID_PARAMETER for Windows956// builds older than 14972.957}958}959throw x;960} finally {961targetBuffer.release();962linkBuffer.release();963}964}965private static native void CreateSymbolicLink0(long linkAddress,966long targetAddress, int flags) throws WindowsException;967968/**969* CreateHardLink(970* LPCTSTR lpFileName,971* LPCTSTR lpExistingFileName,972* LPSECURITY_ATTRIBUTES lpSecurityAttributes973* )974*/975static void CreateHardLink(String newFile, String existingFile)976throws WindowsException977{978NativeBuffer newFileBuffer = asNativeBuffer(newFile);979NativeBuffer existingFileBuffer = asNativeBuffer(existingFile);980try {981CreateHardLink0(newFileBuffer.address(), existingFileBuffer.address());982} finally {983existingFileBuffer.release();984newFileBuffer.release();985}986}987private static native void CreateHardLink0(long newFileBuffer,988long existingFileBuffer) throws WindowsException;989990/**991* GetFullPathName(992* LPCTSTR lpFileName,993* DWORD nBufferLength,994* LPTSTR lpBuffer,995* LPTSTR *lpFilePart996* )997*/998static String GetFullPathName(String path) throws WindowsException {999NativeBuffer buffer = asNativeBuffer(path);1000try {1001return GetFullPathName0(buffer.address());1002} finally {1003buffer.release();1004}1005}1006private static native String GetFullPathName0(long pathAddress)1007throws WindowsException;10081009/**1010* GetFinalPathNameByHandle(1011* HANDLE hFile,1012* LPTSTR lpszFilePath,1013* DWORD cchFilePath,1014* DWORD dwFlags1015* )1016*/1017static native String GetFinalPathNameByHandle(long handle)1018throws WindowsException;10191020/**1021* FormatMessage(1022* DWORD dwFlags,1023* LPCVOID lpSource,1024* DWORD dwMessageId,1025* DWORD dwLanguageId,1026* LPTSTR lpBuffer,1027* DWORD nSize,1028* va_list *Arguments1029* )1030*/1031static native String FormatMessage(int errorCode);10321033/**1034* LocalFree(1035* HLOCAL hMem1036* )1037*/1038static native void LocalFree(long address);10391040/**1041* HANDLE CreateIoCompletionPort (1042* HANDLE FileHandle,1043* HANDLE ExistingCompletionPort,1044* ULONG_PTR CompletionKey,1045* DWORD NumberOfConcurrentThreads1046* )1047*/1048static native long CreateIoCompletionPort(long fileHandle, long existingPort,1049long completionKey) throws WindowsException;105010511052/**1053* GetQueuedCompletionStatus(1054* HANDLE CompletionPort,1055* LPDWORD lpNumberOfBytesTransferred,1056* PULONG_PTR lpCompletionKey,1057* LPOVERLAPPED *lpOverlapped,1058* DWORD dwMilliseconds1059*/1060static CompletionStatus GetQueuedCompletionStatus(long completionPort)1061throws WindowsException1062{1063CompletionStatus status = new CompletionStatus();1064GetQueuedCompletionStatus0(completionPort, status);1065return status;1066}1067static class CompletionStatus {1068private int error;1069private int bytesTransferred;1070private long completionKey;1071private CompletionStatus() { }10721073int error() { return error; }1074int bytesTransferred() { return bytesTransferred; }1075long completionKey() { return completionKey; }1076}1077private static native void GetQueuedCompletionStatus0(long completionPort,1078CompletionStatus status) throws WindowsException;10791080/**1081* PostQueuedCompletionStatus(1082* HANDLE CompletionPort,1083* DWORD dwNumberOfBytesTransferred,1084* ULONG_PTR dwCompletionKey,1085* LPOVERLAPPED lpOverlapped1086* )1087*/1088static native void PostQueuedCompletionStatus(long completionPort,1089long completionKey) throws WindowsException;10901091/**1092* ReadDirectoryChangesW(1093* HANDLE hDirectory,1094* LPVOID lpBuffer,1095* DWORD nBufferLength,1096* BOOL bWatchSubtree,1097* DWORD dwNotifyFilter,1098* LPDWORD lpBytesReturned,1099* LPOVERLAPPED lpOverlapped,1100* LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine1101* )1102*/1103static native void ReadDirectoryChangesW(long hDirectory,1104long bufferAddress,1105int bufferLength,1106boolean watchSubTree,1107int filter,1108long bytesReturnedAddress,1109long pOverlapped)1110throws WindowsException;111111121113/**1114* CancelIo(1115* HANDLE hFile1116* )1117*/1118static native void CancelIo(long hFile) throws WindowsException;11191120/**1121* GetOverlappedResult(1122* HANDLE hFile,1123* LPOVERLAPPED lpOverlapped,1124* LPDWORD lpNumberOfBytesTransferred,1125* BOOL bWait1126* );1127*/1128static native int GetOverlappedResult(long hFile, long lpOverlapped)1129throws WindowsException;11301131// -- support for copying String with a NativeBuffer --11321133private static final Unsafe unsafe = Unsafe.getUnsafe();11341135static NativeBuffer asNativeBuffer(String s) throws WindowsException {1136if (s.length() > (Integer.MAX_VALUE - 2)/2) {1137throw new WindowsException1138("String too long to convert to native buffer");1139}11401141int stringLengthInBytes = s.length() << 1;1142int sizeInBytes = stringLengthInBytes + 2; // char terminator11431144// get a native buffer of sufficient size1145NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(sizeInBytes);1146if (buffer == null) {1147buffer = NativeBuffers.allocNativeBuffer(sizeInBytes);1148} else {1149// buffer already contains the string contents1150if (buffer.owner() == s)1151return buffer;1152}11531154// copy into buffer and zero terminate1155char[] chars = s.toCharArray();1156unsafe.copyMemory(chars, Unsafe.ARRAY_CHAR_BASE_OFFSET, null,1157buffer.address(), (long)stringLengthInBytes);1158unsafe.putChar(buffer.address() + stringLengthInBytes, (char)0);1159buffer.setOwner(s);1160return buffer;1161}11621163// -- native library initialization --11641165private static native void initIDs();11661167static {1168// nio.dll has dependency on net.dll1169jdk.internal.loader.BootLoader.loadLibrary("net");1170jdk.internal.loader.BootLoader.loadLibrary("nio");1171initIDs();1172}11731174}117511761177