1 /*
   2  * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.nio.fs;
  27 
  28 import jdk.internal.misc.Unsafe;
  29 
  30 import static sun.nio.fs.WindowsConstants.*;
  31 
  32 /**
  33  * Win32 and library calls.
  34  */
  35 
  36 class WindowsNativeDispatcher {
  37     private WindowsNativeDispatcher() { }
  38 
  39     /**
  40      * HANDLE CreateEvent(
  41      *   LPSECURITY_ATTRIBUTES lpEventAttributes,
  42      *   BOOL bManualReset,
  43      *   BOOL bInitialState,
  44      *   PCTSTR lpName
  45      * );
  46      */
  47     static native long CreateEvent(boolean bManualReset, boolean bInitialState)
  48         throws WindowsException;
  49 
  50     /**
  51      * HANDLE CreateFile(
  52      *   LPCTSTR lpFileName,
  53      *   DWORD dwDesiredAccess,
  54      *   DWORD dwShareMode,
  55      *   LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  56      *   DWORD dwCreationDisposition,
  57      *   DWORD dwFlagsAndAttributes,
  58      *   HANDLE hTemplateFile
  59      * )
  60      */
  61     static long CreateFile(String path,
  62                            int dwDesiredAccess,
  63                            int dwShareMode,
  64                            long lpSecurityAttributes,
  65                            int dwCreationDisposition,
  66                            int dwFlagsAndAttributes)
  67         throws WindowsException
  68     {
  69         NativeBuffer buffer = asNativeBuffer(path);
  70         try {
  71             return CreateFile0(buffer.address(),
  72                                dwDesiredAccess,
  73                                dwShareMode,
  74                                lpSecurityAttributes,
  75                                dwCreationDisposition,
  76                                dwFlagsAndAttributes);
  77         } finally {
  78             buffer.release();
  79         }
  80     }
  81     static long CreateFile(String path,
  82                            int dwDesiredAccess,
  83                            int dwShareMode,
  84                            int dwCreationDisposition,
  85                            int dwFlagsAndAttributes)
  86         throws WindowsException
  87     {
  88         return CreateFile(path, dwDesiredAccess, dwShareMode, 0L,
  89                           dwCreationDisposition, dwFlagsAndAttributes);
  90     }
  91     private static native long CreateFile0(long lpFileName,
  92                                            int dwDesiredAccess,
  93                                            int dwShareMode,
  94                                            long lpSecurityAttributes,
  95                                            int dwCreationDisposition,
  96                                            int dwFlagsAndAttributes)
  97         throws WindowsException;
  98 
  99     /**
 100      * CloseHandle(
 101      *   HANDLE hObject
 102      * )
 103      */
 104     static native void CloseHandle(long handle);
 105 
 106     /**
 107      * DeleteFile(
 108      *   LPCTSTR lpFileName
 109      * )
 110      */
 111     static void DeleteFile(String path) throws WindowsException {
 112         NativeBuffer buffer = asNativeBuffer(path);
 113         try {
 114             DeleteFile0(buffer.address());
 115         } finally {
 116             buffer.release();
 117         }
 118     }
 119     private static native void DeleteFile0(long lpFileName)
 120         throws WindowsException;
 121 
 122     /**
 123      * CreateDirectory(
 124      *   LPCTSTR lpPathName,
 125      *   LPSECURITY_ATTRIBUTES lpSecurityAttributes
 126      * )
 127      */
 128     static void CreateDirectory(String path, long lpSecurityAttributes) throws WindowsException {
 129         NativeBuffer buffer = asNativeBuffer(path);
 130         try {
 131             CreateDirectory0(buffer.address(), lpSecurityAttributes);
 132         } finally {
 133             buffer.release();
 134         }
 135     }
 136     private static native void CreateDirectory0(long lpFileName, long lpSecurityAttributes)
 137         throws WindowsException;
 138 
 139     /**
 140      * RemoveDirectory(
 141      *   LPCTSTR lpPathName
 142      * )
 143      */
 144     static void RemoveDirectory(String path) throws WindowsException {
 145         NativeBuffer buffer = asNativeBuffer(path);
 146         try {
 147             RemoveDirectory0(buffer.address());
 148         } finally {
 149             buffer.release();
 150         }
 151     }
 152     private static native void RemoveDirectory0(long lpFileName)
 153         throws WindowsException;
 154 
 155     /**
 156      * Marks a file as a sparse file.
 157      *
 158      * DeviceIoControl(
 159      *   FSCTL_SET_SPARSE
 160      * )
 161      */
 162     static native void DeviceIoControlSetSparse(long handle)
 163         throws WindowsException;
 164 
 165     /**
 166      * Retrieves the reparse point data associated with the file or directory.
 167      *
 168      * DeviceIoControl(
 169      *   FSCTL_GET_REPARSE_POINT
 170      * )
 171      */
 172     static native void DeviceIoControlGetReparsePoint(long handle,
 173         long bufferAddress, int bufferSize) throws WindowsException;
 174 
 175     /**
 176      * HANDLE FindFirstFile(
 177      *   LPCTSTR lpFileName,
 178      *   LPWIN32_FIND_DATA lpFindFileData
 179      * )
 180      */
 181     static FirstFile FindFirstFile(String path) throws WindowsException {
 182         NativeBuffer buffer = asNativeBuffer(path);
 183         try {
 184             FirstFile data = new FirstFile();
 185             FindFirstFile0(buffer.address(), data);
 186             return data;
 187         } finally {
 188             buffer.release();
 189         }
 190     }
 191     static class FirstFile {
 192         private long handle;
 193         private String name;
 194         private int attributes;
 195 
 196         private FirstFile() { }
 197         public long handle()    { return handle; }
 198         public String name()    { return name; }
 199         public int attributes() { return attributes; }
 200     }
 201     private static native void FindFirstFile0(long lpFileName, FirstFile obj)
 202         throws WindowsException;
 203 
 204     /**
 205      * HANDLE FindFirstFile(
 206      *   LPCTSTR lpFileName,
 207      *   LPWIN32_FIND_DATA lpFindFileData
 208      * )
 209      */
 210     static long FindFirstFile(String path, long address) throws WindowsException {
 211         NativeBuffer buffer = asNativeBuffer(path);
 212         try {
 213             return FindFirstFile1(buffer.address(), address);
 214         } finally {
 215             buffer.release();
 216         }
 217     }
 218     private static native long FindFirstFile1(long lpFileName, long address)
 219         throws WindowsException;
 220 
 221     /**
 222      * FindNextFile(
 223      *   HANDLE hFindFile,
 224      *   LPWIN32_FIND_DATA lpFindFileData
 225      * )
 226      *
 227      * @return  lpFindFileData->cFileName or null
 228      */
 229     static native String FindNextFile(long handle, long address)
 230         throws WindowsException;
 231 
 232     /**
 233      * HANDLE FindFirstStreamW(
 234      *   LPCWSTR lpFileName,
 235      *   STREAM_INFO_LEVELS InfoLevel,
 236      *   LPVOID lpFindStreamData,
 237      *   DWORD dwFlags
 238      * )
 239      */
 240     static FirstStream FindFirstStream(String path) throws WindowsException {
 241         NativeBuffer buffer = asNativeBuffer(path);
 242         try {
 243             FirstStream data = new FirstStream();
 244             FindFirstStream0(buffer.address(), data);
 245             if (data.handle() == WindowsConstants.INVALID_HANDLE_VALUE)
 246                 return null;
 247             return data;
 248         } finally {
 249             buffer.release();
 250         }
 251     }
 252     static class FirstStream {
 253         private long handle;
 254         private String name;
 255 
 256         private FirstStream() { }
 257         public long handle()    { return handle; }
 258         public String name()    { return name; }
 259     }
 260     private static native void FindFirstStream0(long lpFileName, FirstStream obj)
 261         throws WindowsException;
 262 
 263     /*
 264      * FindNextStreamW(
 265      *   HANDLE hFindStream,
 266      *   LPVOID lpFindStreamData
 267      * )
 268      */
 269     static native String FindNextStream(long handle) throws WindowsException;
 270 
 271     /**
 272      * FindClose(
 273      *   HANDLE hFindFile
 274      * )
 275      */
 276     static native void FindClose(long handle) throws WindowsException;
 277 
 278     /**
 279      * GetFileInformationByHandle(
 280      *   HANDLE hFile,
 281      *   LPBY_HANDLE_FILE_INFORMATION lpFileInformation
 282      * )
 283      */
 284     static native void GetFileInformationByHandle(long handle, long address)
 285         throws WindowsException;
 286 
 287     /**
 288      * CopyFileEx(
 289      *   LPCWSTR lpExistingFileName
 290      *   LPCWSTR lpNewFileName,
 291      *   LPPROGRESS_ROUTINE lpProgressRoutine
 292      *   LPVOID lpData,
 293      *   LPBOOL pbCancel,
 294      *   DWORD dwCopyFlags
 295      * )
 296      */
 297     static void CopyFileEx(String source, String target, int flags,
 298                            long addressToPollForCancel)
 299         throws WindowsException
 300     {
 301         NativeBuffer sourceBuffer = asNativeBuffer(source);
 302         NativeBuffer targetBuffer = asNativeBuffer(target);
 303         try {
 304             CopyFileEx0(sourceBuffer.address(), targetBuffer.address(), flags,
 305                         addressToPollForCancel);
 306         } finally {
 307             targetBuffer.release();
 308             sourceBuffer.release();
 309         }
 310     }
 311     private static native void CopyFileEx0(long existingAddress, long newAddress,
 312         int flags, long addressToPollForCancel) throws WindowsException;
 313 
 314     /**
 315      * MoveFileEx(
 316      *   LPCTSTR lpExistingFileName,
 317      *   LPCTSTR lpNewFileName,
 318      *   DWORD dwFlags
 319      * )
 320      */
 321     static void MoveFileEx(String source, String target, int flags)
 322         throws WindowsException
 323     {
 324         NativeBuffer sourceBuffer = asNativeBuffer(source);
 325         NativeBuffer targetBuffer = asNativeBuffer(target);
 326         try {
 327             MoveFileEx0(sourceBuffer.address(), targetBuffer.address(), flags);
 328         } finally {
 329             targetBuffer.release();
 330             sourceBuffer.release();
 331         }
 332     }
 333     private static native void MoveFileEx0(long existingAddress, long newAddress,
 334         int flags) throws WindowsException;
 335 
 336     /**
 337      * DWORD GetFileAttributes(
 338      *   LPCTSTR lpFileName
 339      * )
 340      */
 341     static int GetFileAttributes(String path) throws WindowsException {
 342         NativeBuffer buffer = asNativeBuffer(path);
 343         try {
 344             return GetFileAttributes0(buffer.address());
 345         } finally {
 346             buffer.release();
 347         }
 348     }
 349     private static native int GetFileAttributes0(long lpFileName)
 350         throws WindowsException;
 351 
 352     /**
 353      * SetFileAttributes(
 354      *   LPCTSTR lpFileName,
 355      *   DWORD dwFileAttributes
 356      */
 357     static void SetFileAttributes(String path, int dwFileAttributes)
 358         throws WindowsException
 359     {
 360         NativeBuffer buffer = asNativeBuffer(path);
 361         try {
 362             SetFileAttributes0(buffer.address(), dwFileAttributes);
 363         } finally {
 364             buffer.release();
 365         }
 366     }
 367     private static native void SetFileAttributes0(long lpFileName,
 368         int dwFileAttributes) throws WindowsException;
 369 
 370     /**
 371      * GetFileAttributesEx(
 372      *   LPCTSTR lpFileName,
 373      *   GET_FILEEX_INFO_LEVELS fInfoLevelId,
 374      *   LPVOID lpFileInformation
 375      * );
 376      */
 377     static void GetFileAttributesEx(String path, long address) throws WindowsException {
 378         NativeBuffer buffer = asNativeBuffer(path);
 379         try {
 380             GetFileAttributesEx0(buffer.address(), address);
 381         } finally {
 382             buffer.release();
 383         }
 384     }
 385     private static native void GetFileAttributesEx0(long lpFileName, long address)
 386         throws WindowsException;
 387     /**
 388      * SetFileTime(
 389      *   HANDLE hFile,
 390      *   CONST FILETIME *lpCreationTime,
 391      *   CONST FILETIME *lpLastAccessTime,
 392      *   CONST FILETIME *lpLastWriteTime
 393      * )
 394      */
 395     static native void SetFileTime(long handle,
 396                                    long createTime,
 397                                    long lastAccessTime,
 398                                    long lastWriteTime)
 399         throws WindowsException;
 400 
 401     /**
 402      * SetEndOfFile(
 403      *   HANDLE hFile
 404      * )
 405      */
 406     static native void SetEndOfFile(long handle) throws WindowsException;
 407 
 408     /**
 409      * DWORD GetLogicalDrives(VOID)
 410      */
 411     static native int GetLogicalDrives() throws WindowsException;
 412 
 413     /**
 414      * GetVolumeInformation(
 415      *   LPCTSTR lpRootPathName,
 416      *   LPTSTR lpVolumeNameBuffer,
 417      *   DWORD nVolumeNameSize,
 418      *   LPDWORD lpVolumeSerialNumber,
 419      *   LPDWORD lpMaximumComponentLength,
 420      *   LPDWORD lpFileSystemFlags,
 421      *   LPTSTR lpFileSystemNameBuffer,
 422      *   DWORD nFileSystemNameSize
 423      * )
 424      */
 425     static VolumeInformation GetVolumeInformation(String root)
 426         throws WindowsException
 427     {
 428         NativeBuffer buffer = asNativeBuffer(root);
 429         try {
 430             VolumeInformation info = new VolumeInformation();
 431             GetVolumeInformation0(buffer.address(), info);
 432             return info;
 433         } finally {
 434             buffer.release();
 435         }
 436     }
 437     static class VolumeInformation {
 438         private String fileSystemName;
 439         private String volumeName;
 440         private int volumeSerialNumber;
 441         private int flags;
 442         private VolumeInformation() { }
 443 
 444         public String fileSystemName()      { return fileSystemName; }
 445         public String volumeName()          { return volumeName; }
 446         public int volumeSerialNumber()     { return volumeSerialNumber; }
 447         public int flags()                  { return flags; }
 448     }
 449     private static native void GetVolumeInformation0(long lpRoot,
 450                                                      VolumeInformation obj)
 451         throws WindowsException;
 452 
 453     /**
 454      * UINT GetDriveType(
 455      *   LPCTSTR lpRootPathName
 456      * )
 457      */
 458     static int GetDriveType(String root) throws WindowsException {
 459         NativeBuffer buffer = asNativeBuffer(root);
 460         try {
 461             return GetDriveType0(buffer.address());
 462         } finally {
 463             buffer.release();
 464         }
 465     }
 466     private static native int GetDriveType0(long lpRoot) throws WindowsException;
 467 
 468     /**
 469      * GetDiskFreeSpaceEx(
 470      *   LPCTSTR lpDirectoryName,
 471      *   PULARGE_INTEGER lpFreeBytesAvailableToCaller,
 472      *   PULARGE_INTEGER lpTotalNumberOfBytes,
 473      *   PULARGE_INTEGER lpTotalNumberOfFreeBytes
 474      * )
 475      */
 476     static DiskFreeSpace GetDiskFreeSpaceEx(String path)
 477         throws WindowsException
 478     {
 479         NativeBuffer buffer = asNativeBuffer(path);
 480         try {
 481             DiskFreeSpace space = new DiskFreeSpace();
 482             GetDiskFreeSpaceEx0(buffer.address(), space);
 483             return space;
 484         } finally {
 485             buffer.release();
 486         }
 487     }
 488 
 489     /**
 490      * GetDiskFreeSpace(
 491      *   LPCTSTR lpRootPathName,
 492      *   LPDWORD lpSectorsPerCluster,
 493      *   LPDWORD lpBytesPerSector,
 494      *   LPDWORD lpNumberOfFreeClusters,
 495      *   LPDWORD lpTotalNumberOfClusters
 496      * )
 497      */
 498     static DiskFreeSpace GetDiskFreeSpace(String path)
 499         throws WindowsException
 500     {
 501         NativeBuffer buffer = asNativeBuffer(path);
 502         try {
 503             DiskFreeSpace space = new DiskFreeSpace();
 504             GetDiskFreeSpace0(buffer.address(), space);
 505             return space;
 506         } finally {
 507             buffer.release();
 508         }
 509     }
 510 
 511     static class DiskFreeSpace {
 512         private long freeBytesAvailable;
 513         private long totalNumberOfBytes;
 514         private long totalNumberOfFreeBytes;
 515         private long bytesPerSector;
 516         private DiskFreeSpace() { }
 517 
 518         public long freeBytesAvailable()      { return freeBytesAvailable; }
 519         public long totalNumberOfBytes()      { return totalNumberOfBytes; }
 520         public long totalNumberOfFreeBytes()  { return totalNumberOfFreeBytes; }
 521         public long bytesPerSector()          { return bytesPerSector; }
 522     }
 523     private static native void GetDiskFreeSpaceEx0(long lpDirectoryName,
 524                                                    DiskFreeSpace obj)
 525         throws WindowsException;
 526 
 527 
 528     private static native void GetDiskFreeSpace0(long lpRootPathName,
 529                                                  DiskFreeSpace obj)
 530         throws WindowsException;
 531 
 532     /**
 533      * GetVolumePathName(
 534      *   LPCTSTR lpszFileName,
 535      *   LPTSTR lpszVolumePathName,
 536      *   DWORD cchBufferLength
 537      * )
 538      *
 539      * @return  lpFileName
 540      */
 541     static String GetVolumePathName(String path) throws WindowsException {
 542         NativeBuffer buffer = asNativeBuffer(path);
 543         try {
 544             return GetVolumePathName0(buffer.address());
 545         } finally {
 546             buffer.release();
 547         }
 548     }
 549     private static native String GetVolumePathName0(long lpFileName)
 550         throws WindowsException;
 551 
 552 
 553     /**
 554      * InitializeSecurityDescriptor(
 555      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 556      *   DWORD dwRevision
 557      * )
 558      */
 559     static native void InitializeSecurityDescriptor(long sdAddress)
 560         throws WindowsException;
 561 
 562     /**
 563      * InitializeAcl(
 564      *   PACL pAcl,
 565      *   DWORD nAclLength,
 566      *   DWORD dwAclRevision
 567      * )
 568      */
 569     static native void InitializeAcl(long aclAddress, int size)
 570          throws WindowsException;
 571 
 572     /**
 573      * GetFileSecurity(
 574      *   LPCTSTR lpFileName,
 575      *   SECURITY_INFORMATION RequestedInformation,
 576      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 577      *   DWORD nLength,
 578      *   LPDWORD lpnLengthNeeded
 579      * )
 580      */
 581     static int GetFileSecurity(String path,
 582                                int requestedInformation,
 583                                long pSecurityDescriptor,
 584                                int nLength) throws WindowsException
 585     {
 586         NativeBuffer buffer = asNativeBuffer(path);
 587         try {
 588             return GetFileSecurity0(buffer.address(), requestedInformation,
 589                 pSecurityDescriptor, nLength);
 590         } finally {
 591             buffer.release();
 592         }
 593     }
 594     private static native int GetFileSecurity0(long lpFileName,
 595                                                int requestedInformation,
 596                                                long pSecurityDescriptor,
 597                                                int nLength) throws WindowsException;
 598 
 599     /**
 600      * SetFileSecurity(
 601      *   LPCTSTR lpFileName,
 602      *   SECURITY_INFORMATION SecurityInformation,
 603      *   PSECURITY_DESCRIPTOR pSecurityDescriptor
 604      * )
 605      */
 606     static void SetFileSecurity(String path,
 607                                 int securityInformation,
 608                                 long pSecurityDescriptor)
 609         throws WindowsException
 610     {
 611         NativeBuffer buffer = asNativeBuffer(path);
 612         try {
 613             SetFileSecurity0(buffer.address(), securityInformation,
 614                 pSecurityDescriptor);
 615         } finally {
 616             buffer.release();
 617         }
 618     }
 619     static native void SetFileSecurity0(long lpFileName, int securityInformation,
 620         long pSecurityDescriptor) throws WindowsException;
 621 
 622     /**
 623      * GetSecurityDescriptorOwner(
 624      *   PSECURITY_DESCRIPTOR pSecurityDescriptor
 625      *   PSID *pOwner,
 626      *   LPBOOL lpbOwnerDefaulted
 627      * )
 628      *
 629      * @return  pOwner
 630      */
 631     static native long GetSecurityDescriptorOwner(long pSecurityDescriptor)
 632         throws WindowsException;
 633 
 634     /**
 635      * SetSecurityDescriptorOwner(
 636      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 637      *   PSID pOwner,
 638      *   BOOL bOwnerDefaulted
 639      * )
 640      */
 641     static native void SetSecurityDescriptorOwner(long pSecurityDescriptor,
 642                                                   long pOwner)
 643         throws WindowsException;
 644 
 645     /**
 646      * GetSecurityDescriptorDacl(
 647      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 648      *   LPBOOL lpbDaclPresent,
 649      *   PACL *pDacl,
 650      *   LPBOOL lpbDaclDefaulted
 651      * )
 652      */
 653     static native long GetSecurityDescriptorDacl(long pSecurityDescriptor);
 654 
 655     /**
 656      * SetSecurityDescriptorDacl(
 657      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 658      *   BOOL bDaclPresent,
 659      *   PACL pDacl,
 660      *   BOOL bDaclDefaulted
 661      * )
 662      */
 663     static native void SetSecurityDescriptorDacl(long pSecurityDescriptor, long pAcl)
 664         throws WindowsException;
 665 
 666 
 667     /**
 668      * GetAclInformation(
 669      *   PACL pAcl,
 670      *   LPVOID pAclInformation,
 671      *   DWORD nAclInformationLength,
 672      *   ACL_INFORMATION_CLASS dwAclInformationClass
 673      * )
 674      */
 675     static AclInformation GetAclInformation(long aclAddress) {
 676         AclInformation info = new AclInformation();
 677         GetAclInformation0(aclAddress, info);
 678         return info;
 679     }
 680     static class AclInformation {
 681         private int aceCount;
 682         private AclInformation() { }
 683 
 684         public int aceCount()   { return aceCount; }
 685     }
 686     private static native void GetAclInformation0(long aclAddress,
 687         AclInformation obj);
 688 
 689     /**
 690      * GetAce(
 691      *   PACL pAcl,
 692      *   DWORD dwAceIndex,
 693      *   LPVOID *pAce
 694      * )
 695      */
 696     static native long GetAce(long aclAddress, int aceIndex);
 697 
 698     /**
 699      * AddAccessAllowedAceEx(
 700      *   PACL pAcl,
 701      *   DWORD dwAceRevision,
 702      *   DWORD AceFlags,
 703      *   DWORD AccessMask,
 704      *   PSID pSid
 705      * )
 706      */
 707     static native void AddAccessAllowedAceEx(long aclAddress, int flags,
 708         int mask, long sidAddress) throws WindowsException;
 709 
 710     /**
 711      * AddAccessDeniedAceEx(
 712      *   PACL pAcl,
 713      *   DWORD dwAceRevision,
 714      *   DWORD AceFlags,
 715      *   DWORD AccessMask,
 716      *   PSID pSid
 717      * )
 718      */
 719     static native void AddAccessDeniedAceEx(long aclAddress, int flags,
 720         int mask, long sidAddress) throws WindowsException;
 721 
 722     /**
 723      * LookupAccountSid(
 724      *   LPCTSTR lpSystemName,
 725      *   PSID Sid,
 726      *   LPTSTR Name,
 727      *   LPDWORD cbName,
 728      *   LPTSTR ReferencedDomainName,
 729      *   LPDWORD cbReferencedDomainName,
 730      *   PSID_NAME_USE peUse
 731      * )
 732      */
 733     static Account LookupAccountSid(long sidAddress) throws WindowsException {
 734         Account acc = new Account();
 735         LookupAccountSid0(sidAddress, acc);
 736         return acc;
 737     }
 738     static class Account {
 739         private String domain;
 740         private String name;
 741         private int use;
 742         private Account() { }
 743 
 744         public String domain()  { return domain; }
 745         public String name()    { return name; }
 746         public int use()        { return use; }
 747     }
 748     private static native void LookupAccountSid0(long sidAddress, Account obj)
 749         throws WindowsException;
 750 
 751     /**
 752      * LookupAccountName(
 753      *   LPCTSTR lpSystemName,
 754      *   LPCTSTR lpAccountName,
 755      *   PSID Sid,
 756      *   LPDWORD cbSid,
 757      *   LPTSTR ReferencedDomainName,
 758      *   LPDWORD cbReferencedDomainName,
 759      *   PSID_NAME_USE peUse
 760      * )
 761      *
 762      * @return  cbSid
 763      */
 764     static int LookupAccountName(String accountName,
 765                                  long pSid,
 766                                  int cbSid) throws WindowsException
 767     {
 768         NativeBuffer buffer = asNativeBuffer(accountName);
 769         try {
 770             return LookupAccountName0(buffer.address(), pSid, cbSid);
 771         } finally {
 772             buffer.release();
 773         }
 774     }
 775     private static native int LookupAccountName0(long lpAccountName, long pSid,
 776         int cbSid) throws WindowsException;
 777 
 778     /**
 779      * DWORD GetLengthSid(
 780      *   PSID pSid
 781      * )
 782      */
 783     static native int GetLengthSid(long sidAddress);
 784 
 785     /**
 786      * ConvertSidToStringSid(
 787      *   PSID Sid,
 788      *   LPTSTR* StringSid
 789      * )
 790      *
 791      * @return  StringSid
 792      */
 793     static native String ConvertSidToStringSid(long sidAddress)
 794         throws WindowsException;
 795 
 796     /**
 797      * ConvertStringSidToSid(
 798      *   LPCTSTR StringSid,
 799      *   PSID* pSid
 800      * )
 801      *
 802      * @return  pSid
 803      */
 804     static long ConvertStringSidToSid(String sidString)
 805         throws WindowsException
 806     {
 807         NativeBuffer buffer = asNativeBuffer(sidString);
 808         try {
 809             return ConvertStringSidToSid0(buffer.address());
 810         } finally {
 811             buffer.release();
 812         }
 813     }
 814     private static native long ConvertStringSidToSid0(long lpStringSid)
 815         throws WindowsException;
 816 
 817     /**
 818      * HANDLE GetCurrentProcess(VOID)
 819      */
 820     static native long GetCurrentProcess();
 821 
 822     /**
 823      * HANDLE GetCurrentThread(VOID)
 824      */
 825     static native long GetCurrentThread();
 826 
 827     /**
 828      * OpenProcessToken(
 829      *   HANDLE ProcessHandle,
 830      *   DWORD DesiredAccess,
 831      *   PHANDLE TokenHandle
 832      * )
 833      */
 834     static native long OpenProcessToken(long hProcess, int desiredAccess)
 835         throws WindowsException;
 836 
 837     /**
 838      * OpenThreadToken(
 839      *   HANDLE ThreadHandle,
 840      *   DWORD DesiredAccess,
 841      *   BOOL OpenAsSelf,
 842      *   PHANDLE TokenHandle
 843      * )
 844      */
 845     static native long OpenThreadToken(long hThread, int desiredAccess,
 846         boolean openAsSelf) throws WindowsException;
 847 
 848     /**
 849      */
 850     static native long DuplicateTokenEx(long hThread, int desiredAccess)
 851         throws WindowsException;
 852 
 853     /**
 854      * SetThreadToken(
 855      *   PHANDLE Thread,
 856      *   HANDLE Token
 857      * )
 858      */
 859     static native void SetThreadToken(long thread, long hToken)
 860         throws WindowsException;
 861 
 862     /**
 863      * GetTokenInformation(
 864      *   HANDLE TokenHandle,
 865      *   TOKEN_INFORMATION_CLASS TokenInformationClass,
 866      *   LPVOID TokenInformation,
 867      *   DWORD TokenInformationLength,
 868      *   PDWORD ReturnLength
 869      * )
 870      */
 871     static native int GetTokenInformation(long token, int tokenInfoClass,
 872         long pTokenInfo, int tokenInfoLength) throws WindowsException;
 873 
 874     /**
 875      * AdjustTokenPrivileges(
 876      *   HANDLE TokenHandle,
 877      *   BOOL DisableAllPrivileges
 878      *   PTOKEN_PRIVILEGES NewState
 879      *   DWORD BufferLength
 880      *   PTOKEN_PRIVILEGES
 881      *   PDWORD ReturnLength
 882      * )
 883      */
 884     static native void AdjustTokenPrivileges(long token, long luid, int attributes)
 885         throws WindowsException;
 886 
 887 
 888     /**
 889      * AccessCheck(
 890      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 891      *   HANDLE ClientToken,
 892      *   DWORD DesiredAccess,
 893      *   PGENERIC_MAPPING GenericMapping,
 894      *   PPRIVILEGE_SET PrivilegeSet,
 895      *   LPDWORD PrivilegeSetLength,
 896      *   LPDWORD GrantedAccess,
 897      *   LPBOOL AccessStatus
 898      * )
 899      */
 900     static native boolean AccessCheck(long token, long securityInfo, int accessMask,
 901         int genericRead, int genericWrite, int genericExecute, int genericAll)
 902         throws WindowsException;
 903 
 904     /**
 905      */
 906     static long LookupPrivilegeValue(String name) throws WindowsException {
 907         NativeBuffer buffer = asNativeBuffer(name);
 908         try {
 909             return LookupPrivilegeValue0(buffer.address());
 910         } finally {
 911             buffer.release();
 912         }
 913     }
 914     private static native long LookupPrivilegeValue0(long lpName)
 915         throws WindowsException;
 916 
 917     /**
 918      * CreateSymbolicLink(
 919      *   LPCWSTR lpSymlinkFileName,
 920      *   LPCWSTR lpTargetFileName,
 921      *   DWORD dwFlags
 922      * )
 923      *
 924      * Creates a symbolic link, conditionally retrying with the addition of
 925      * the flag SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE if the initial
 926      * attempt fails with ERROR_PRIVILEGE_NOT_HELD. If the retry fails, throw
 927      * the original exception due to ERROR_PRIVILEGE_NOT_HELD. The retry will
 928      * succeed only on Windows build 14972 or later if Developer Mode is on.
 929      */
 930     static void CreateSymbolicLink(String link, String target, int flags)
 931         throws WindowsException
 932     {
 933         NativeBuffer linkBuffer = asNativeBuffer(link);
 934         NativeBuffer targetBuffer = asNativeBuffer(target);
 935         try {
 936             CreateSymbolicLink0(linkBuffer.address(), targetBuffer.address(),
 937                                 flags);
 938         } catch (WindowsException x) {
 939             if (x.lastError() == ERROR_PRIVILEGE_NOT_HELD) {
 940                 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
 941                 try {
 942                     CreateSymbolicLink0(linkBuffer.address(),
 943                                         targetBuffer.address(), flags);
 944                     return;
 945                 } catch (WindowsException ignored) {
 946                     // Will fail with ERROR_INVALID_PARAMETER for Windows
 947                     // builds older than 14972.
 948                 }
 949             }
 950             throw x;
 951         } finally {
 952             targetBuffer.release();
 953             linkBuffer.release();
 954         }
 955     }
 956     private static native void CreateSymbolicLink0(long linkAddress,
 957         long targetAddress, int flags) throws WindowsException;
 958 
 959     /**
 960      * CreateHardLink(
 961      *    LPCTSTR lpFileName,
 962      *    LPCTSTR lpExistingFileName,
 963      *    LPSECURITY_ATTRIBUTES lpSecurityAttributes
 964      * )
 965      */
 966     static void CreateHardLink(String newFile, String existingFile)
 967         throws WindowsException
 968     {
 969         NativeBuffer newFileBuffer = asNativeBuffer(newFile);
 970         NativeBuffer existingFileBuffer = asNativeBuffer(existingFile);
 971         try {
 972             CreateHardLink0(newFileBuffer.address(), existingFileBuffer.address());
 973         } finally {
 974             existingFileBuffer.release();
 975             newFileBuffer.release();
 976         }
 977     }
 978     private static native void CreateHardLink0(long newFileBuffer,
 979         long existingFileBuffer) throws WindowsException;
 980 
 981     /**
 982      * GetFullPathName(
 983      *   LPCTSTR lpFileName,
 984      *   DWORD nBufferLength,
 985      *   LPTSTR lpBuffer,
 986      *   LPTSTR *lpFilePart
 987      * )
 988      */
 989     static String GetFullPathName(String path) throws WindowsException {
 990         NativeBuffer buffer = asNativeBuffer(path);
 991         try {
 992             return GetFullPathName0(buffer.address());
 993         } finally {
 994             buffer.release();
 995         }
 996     }
 997     private static native String GetFullPathName0(long pathAddress)
 998         throws WindowsException;
 999 
1000     /**
1001      * GetFinalPathNameByHandle(
1002      *   HANDLE hFile,
1003      *   LPTSTR lpszFilePath,
1004      *   DWORD cchFilePath,
1005      *   DWORD dwFlags
1006      * )
1007      */
1008     static native String GetFinalPathNameByHandle(long handle)
1009         throws WindowsException;
1010 
1011     /**
1012      * FormatMessage(
1013      *   DWORD dwFlags,
1014      *   LPCVOID lpSource,
1015      *   DWORD dwMessageId,
1016      *   DWORD dwLanguageId,
1017      *   LPTSTR lpBuffer,
1018      *   DWORD nSize,
1019      *   va_list *Arguments
1020      * )
1021      */
1022     static native String FormatMessage(int errorCode);
1023 
1024     /**
1025      * LocalFree(
1026      *   HLOCAL hMem
1027      * )
1028      */
1029     static native void LocalFree(long address);
1030 
1031     /**
1032      * HANDLE CreateIoCompletionPort (
1033      *   HANDLE FileHandle,
1034      *   HANDLE ExistingCompletionPort,
1035      *   ULONG_PTR CompletionKey,
1036      *   DWORD NumberOfConcurrentThreads
1037      * )
1038      */
1039     static native long CreateIoCompletionPort(long fileHandle, long existingPort,
1040         long completionKey) throws WindowsException;
1041 
1042 
1043     /**
1044      * GetQueuedCompletionStatus(
1045      *   HANDLE CompletionPort,
1046      *   LPDWORD lpNumberOfBytesTransferred,
1047      *   PULONG_PTR lpCompletionKey,
1048      *   LPOVERLAPPED *lpOverlapped,
1049      *   DWORD dwMilliseconds
1050      */
1051     static CompletionStatus GetQueuedCompletionStatus(long completionPort)
1052         throws WindowsException
1053     {
1054         CompletionStatus status = new CompletionStatus();
1055         GetQueuedCompletionStatus0(completionPort, status);
1056         return status;
1057     }
1058     static class CompletionStatus {
1059         private int error;
1060         private int bytesTransferred;
1061         private long completionKey;
1062         private CompletionStatus() { }
1063 
1064         int error() { return error; }
1065         int bytesTransferred() { return bytesTransferred; }
1066         long completionKey() { return completionKey; }
1067     }
1068     private static native void GetQueuedCompletionStatus0(long completionPort,
1069         CompletionStatus status) throws WindowsException;
1070 
1071     /**
1072      * PostQueuedCompletionStatus(
1073      *   HANDLE CompletionPort,
1074      *   DWORD dwNumberOfBytesTransferred,
1075      *   ULONG_PTR dwCompletionKey,
1076      *   LPOVERLAPPED lpOverlapped
1077      * )
1078      */
1079     static native void PostQueuedCompletionStatus(long completionPort,
1080         long completionKey) throws WindowsException;
1081 
1082     /**
1083      * ReadDirectoryChangesW(
1084      *   HANDLE hDirectory,
1085      *   LPVOID lpBuffer,
1086      *   DWORD nBufferLength,
1087      *   BOOL bWatchSubtree,
1088      *   DWORD dwNotifyFilter,
1089      *   LPDWORD lpBytesReturned,
1090      *   LPOVERLAPPED lpOverlapped,
1091      *   LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
1092      * )
1093      */
1094     static native void ReadDirectoryChangesW(long hDirectory,
1095                                              long bufferAddress,
1096                                              int bufferLength,
1097                                              boolean watchSubTree,
1098                                              int filter,
1099                                              long bytesReturnedAddress,
1100                                              long pOverlapped)
1101         throws WindowsException;
1102 
1103 
1104     /**
1105      * CancelIo(
1106      *   HANDLE hFile
1107      * )
1108      */
1109     static native void CancelIo(long hFile) throws WindowsException;
1110 
1111     /**
1112      * GetOverlappedResult(
1113      *   HANDLE hFile,
1114      *   LPOVERLAPPED lpOverlapped,
1115      *   LPDWORD lpNumberOfBytesTransferred,
1116      *   BOOL bWait
1117      * );
1118      */
1119     static native int GetOverlappedResult(long hFile, long lpOverlapped)
1120         throws WindowsException;
1121 
1122     // -- support for copying String with a NativeBuffer --
1123 
1124     private static final Unsafe unsafe = Unsafe.getUnsafe();
1125 
1126     static NativeBuffer asNativeBuffer(String s) {
1127         int stringLengthInBytes = s.length() << 1;
1128         int sizeInBytes = stringLengthInBytes + 2;  // char terminator
1129 
1130         // get a native buffer of sufficient size
1131         NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(sizeInBytes);
1132         if (buffer == null) {
1133             buffer = NativeBuffers.allocNativeBuffer(sizeInBytes);
1134         } else {
1135             // buffer already contains the string contents
1136             if (buffer.owner() == s)
1137                 return buffer;
1138         }
1139 
1140         // copy into buffer and zero terminate
1141         char[] chars = s.toCharArray();
1142         unsafe.copyMemory(chars, Unsafe.ARRAY_CHAR_BASE_OFFSET, null,
1143             buffer.address(), (long)stringLengthInBytes);
1144         unsafe.putChar(buffer.address() + stringLengthInBytes, (char)0);
1145         buffer.setOwner(s);
1146         return buffer;
1147     }
1148 
1149     // -- native library initialization --
1150 
1151     private static native void initIDs();
1152 
1153     static {
1154         // nio.dll has dependency on net.dll
1155         jdk.internal.access.SharedSecrets.getJavaLangAccess()
1156                 .loadLibrary(WindowsNativeDispatcher.class, "net");
1157         jdk.internal.access.SharedSecrets.getJavaLangAccess()
1158                 .loadLibrary(WindowsNativeDispatcher.class, "nio");
1159         initIDs();
1160     }
1161 
1162 }