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