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