1 /*
   2  * Copyright (c) 2008, 2013, 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 sun.misc.Unsafe;
  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     static class DiskFreeSpace {
 489         private long freeBytesAvailable;
 490         private long totalNumberOfBytes;
 491         private long totalNumberOfFreeBytes;
 492         private DiskFreeSpace() { }
 493 
 494         public long freeBytesAvailable()      { return freeBytesAvailable; }
 495         public long totalNumberOfBytes()      { return totalNumberOfBytes; }
 496         public long totalNumberOfFreeBytes()  { return totalNumberOfFreeBytes; }
 497     }
 498     private static native void GetDiskFreeSpaceEx0(long lpDirectoryName,
 499                                                    DiskFreeSpace obj)
 500         throws WindowsException;
 501 
 502 
 503     /**
 504      * GetVolumePathName(
 505      *   LPCTSTR lpszFileName,
 506      *   LPTSTR lpszVolumePathName,
 507      *   DWORD cchBufferLength
 508      * )
 509      *
 510      * @return  lpFileName
 511      */
 512     static String GetVolumePathName(String path) throws WindowsException {
 513         NativeBuffer buffer = asNativeBuffer(path);
 514         try {
 515             return GetVolumePathName0(buffer.address());
 516         } finally {
 517             buffer.release();
 518         }
 519     }
 520     private static native String GetVolumePathName0(long lpFileName)
 521         throws WindowsException;
 522 
 523 
 524     /**
 525      * InitializeSecurityDescriptor(
 526      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 527      *   DWORD dwRevision
 528      * )
 529      */
 530     static native void InitializeSecurityDescriptor(long sdAddress)
 531         throws WindowsException;
 532 
 533     /**
 534      * InitializeAcl(
 535      *   PACL pAcl,
 536      *   DWORD nAclLength,
 537      *   DWORD dwAclRevision
 538      * )
 539      */
 540     static native void InitializeAcl(long aclAddress, int size)
 541          throws WindowsException;
 542 
 543     /**
 544      * GetFileSecurity(
 545      *   LPCTSTR lpFileName,
 546      *   SECURITY_INFORMATION RequestedInformation,
 547      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 548      *   DWORD nLength,
 549      *   LPDWORD lpnLengthNeeded
 550      * )
 551      */
 552     static int GetFileSecurity(String path,
 553                                int requestedInformation,
 554                                long pSecurityDescriptor,
 555                                int nLength) throws WindowsException
 556     {
 557         NativeBuffer buffer = asNativeBuffer(path);
 558         try {
 559             return GetFileSecurity0(buffer.address(), requestedInformation,
 560                 pSecurityDescriptor, nLength);
 561         } finally {
 562             buffer.release();
 563         }
 564     }
 565     private static native int GetFileSecurity0(long lpFileName,
 566                                                int requestedInformation,
 567                                                long pSecurityDescriptor,
 568                                                int nLength) throws WindowsException;
 569 
 570     /**
 571      * SetFileSecurity(
 572      *   LPCTSTR lpFileName,
 573      *   SECURITY_INFORMATION SecurityInformation,
 574      *   PSECURITY_DESCRIPTOR pSecurityDescriptor
 575      * )
 576      */
 577     static void SetFileSecurity(String path,
 578                                 int securityInformation,
 579                                 long pSecurityDescriptor)
 580         throws WindowsException
 581     {
 582         NativeBuffer buffer = asNativeBuffer(path);
 583         try {
 584             SetFileSecurity0(buffer.address(), securityInformation,
 585                 pSecurityDescriptor);
 586         } finally {
 587             buffer.release();
 588         }
 589     }
 590     static native void SetFileSecurity0(long lpFileName, int securityInformation,
 591         long pSecurityDescriptor) throws WindowsException;
 592 
 593     /**
 594      * GetSecurityDescriptorOwner(
 595      *   PSECURITY_DESCRIPTOR pSecurityDescriptor
 596      *   PSID *pOwner,
 597      *   LPBOOL lpbOwnerDefaulted
 598      * )
 599      *
 600      * @return  pOwner
 601      */
 602     static native long GetSecurityDescriptorOwner(long pSecurityDescriptor)
 603         throws WindowsException;
 604 
 605     /**
 606      * SetSecurityDescriptorOwner(
 607      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 608      *   PSID pOwner,
 609      *   BOOL bOwnerDefaulted
 610      * )
 611      */
 612     static native void SetSecurityDescriptorOwner(long pSecurityDescriptor,
 613                                                   long pOwner)
 614         throws WindowsException;
 615 
 616     /**
 617      * GetSecurityDescriptorDacl(
 618      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 619      *   LPBOOL lpbDaclPresent,
 620      *   PACL *pDacl,
 621      *   LPBOOL lpbDaclDefaulted
 622      * )
 623      */
 624     static native long GetSecurityDescriptorDacl(long pSecurityDescriptor);
 625 
 626     /**
 627      * SetSecurityDescriptorDacl(
 628      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 629      *   BOOL bDaclPresent,
 630      *   PACL pDacl,
 631      *   BOOL bDaclDefaulted
 632      * )
 633      */
 634     static native void SetSecurityDescriptorDacl(long pSecurityDescriptor, long pAcl)
 635         throws WindowsException;
 636 
 637 
 638     /**
 639      * GetAclInformation(
 640      *   PACL pAcl,
 641      *   LPVOID pAclInformation,
 642      *   DWORD nAclInformationLength,
 643      *   ACL_INFORMATION_CLASS dwAclInformationClass
 644      * )
 645      */
 646     static AclInformation GetAclInformation(long aclAddress) {
 647         AclInformation info = new AclInformation();
 648         GetAclInformation0(aclAddress, info);
 649         return info;
 650     }
 651     static class AclInformation {
 652         private int aceCount;
 653         private AclInformation() { }
 654 
 655         public int aceCount()   { return aceCount; }
 656     }
 657     private static native void GetAclInformation0(long aclAddress,
 658         AclInformation obj);
 659 
 660     /**
 661      * GetAce(
 662      *   PACL pAcl,
 663      *   DWORD dwAceIndex,
 664      *   LPVOID *pAce
 665      * )
 666      */
 667     static native long GetAce(long aclAddress, int aceIndex);
 668 
 669     /**
 670      * AddAccessAllowedAceEx(
 671      *   PACL pAcl,
 672      *   DWORD dwAceRevision,
 673      *   DWORD AceFlags,
 674      *   DWORD AccessMask,
 675      *   PSID pSid
 676      * )
 677      */
 678     static native void AddAccessAllowedAceEx(long aclAddress, int flags,
 679         int mask, long sidAddress) throws WindowsException;
 680 
 681     /**
 682      * AddAccessDeniedAceEx(
 683      *   PACL pAcl,
 684      *   DWORD dwAceRevision,
 685      *   DWORD AceFlags,
 686      *   DWORD AccessMask,
 687      *   PSID pSid
 688      * )
 689      */
 690     static native void AddAccessDeniedAceEx(long aclAddress, int flags,
 691         int mask, long sidAddress) throws WindowsException;
 692 
 693     /**
 694      * LookupAccountSid(
 695      *   LPCTSTR lpSystemName,
 696      *   PSID Sid,
 697      *   LPTSTR Name,
 698      *   LPDWORD cbName,
 699      *   LPTSTR ReferencedDomainName,
 700      *   LPDWORD cbReferencedDomainName,
 701      *   PSID_NAME_USE peUse
 702      * )
 703      */
 704     static Account LookupAccountSid(long sidAddress) throws WindowsException {
 705         Account acc = new Account();
 706         LookupAccountSid0(sidAddress, acc);
 707         return acc;
 708     }
 709     static class Account {
 710         private String domain;
 711         private String name;
 712         private int use;
 713         private Account() { }
 714 
 715         public String domain()  { return domain; }
 716         public String name()    { return name; }
 717         public int use()        { return use; }
 718     }
 719     private static native void LookupAccountSid0(long sidAddress, Account obj)
 720         throws WindowsException;
 721 
 722     /**
 723      * LookupAccountName(
 724      *   LPCTSTR lpSystemName,
 725      *   LPCTSTR lpAccountName,
 726      *   PSID Sid,
 727      *   LPDWORD cbSid,
 728      *   LPTSTR ReferencedDomainName,
 729      *   LPDWORD cbReferencedDomainName,
 730      *   PSID_NAME_USE peUse
 731      * )
 732      *
 733      * @return  cbSid
 734      */
 735     static int LookupAccountName(String accountName,
 736                                  long pSid,
 737                                  int cbSid) throws WindowsException
 738     {
 739         NativeBuffer buffer = asNativeBuffer(accountName);
 740         try {
 741             return LookupAccountName0(buffer.address(), pSid, cbSid);
 742         } finally {
 743             buffer.release();
 744         }
 745     }
 746     private static native int LookupAccountName0(long lpAccountName, long pSid,
 747         int cbSid) throws WindowsException;
 748 
 749     /**
 750      * DWORD GetLengthSid(
 751      *   PSID pSid
 752      * )
 753      */
 754     static native int GetLengthSid(long sidAddress);
 755 
 756     /**
 757      * ConvertSidToStringSid(
 758      *   PSID Sid,
 759      *   LPTSTR* StringSid
 760      * )
 761      *
 762      * @return  StringSid
 763      */
 764     static native String ConvertSidToStringSid(long sidAddress)
 765         throws WindowsException;
 766 
 767     /**
 768      * ConvertStringSidToSid(
 769      *   LPCTSTR StringSid,
 770      *   PSID* pSid
 771      * )
 772      *
 773      * @return  pSid
 774      */
 775     static long ConvertStringSidToSid(String sidString)
 776         throws WindowsException
 777     {
 778         NativeBuffer buffer = asNativeBuffer(sidString);
 779         try {
 780             return ConvertStringSidToSid0(buffer.address());
 781         } finally {
 782             buffer.release();
 783         }
 784     }
 785     private static native long ConvertStringSidToSid0(long lpStringSid)
 786         throws WindowsException;
 787 
 788     /**
 789      * HANDLE GetCurrentProcess(VOID)
 790      */
 791     static native long GetCurrentProcess();
 792 
 793     /**
 794      * HANDLE GetCurrentThread(VOID)
 795      */
 796     static native long GetCurrentThread();
 797 
 798     /**
 799      * OpenProcessToken(
 800      *   HANDLE ProcessHandle,
 801      *   DWORD DesiredAccess,
 802      *   PHANDLE TokenHandle
 803      * )
 804      */
 805     static native long OpenProcessToken(long hProcess, int desiredAccess)
 806         throws WindowsException;
 807 
 808     /**
 809      * OpenThreadToken(
 810      *   HANDLE ThreadHandle,
 811      *   DWORD DesiredAccess,
 812      *   BOOL OpenAsSelf,
 813      *   PHANDLE TokenHandle
 814      * )
 815      */
 816     static native long OpenThreadToken(long hThread, int desiredAccess,
 817         boolean openAsSelf) throws WindowsException;
 818 
 819     /**
 820      */
 821     static native long DuplicateTokenEx(long hThread, int desiredAccess)
 822         throws WindowsException;
 823 
 824     /**
 825      * SetThreadToken(
 826      *   PHANDLE Thread,
 827      *   HANDLE Token
 828      * )
 829      */
 830     static native void SetThreadToken(long thread, long hToken)
 831         throws WindowsException;
 832 
 833     /**
 834      * GetTokenInformation(
 835      *   HANDLE TokenHandle,
 836      *   TOKEN_INFORMATION_CLASS TokenInformationClass,
 837      *   LPVOID TokenInformation,
 838      *   DWORD TokenInformationLength,
 839      *   PDWORD ReturnLength
 840      * )
 841      */
 842     static native int GetTokenInformation(long token, int tokenInfoClass,
 843         long pTokenInfo, int tokenInfoLength) throws WindowsException;
 844 
 845     /**
 846      * AdjustTokenPrivileges(
 847      *   HANDLE TokenHandle,
 848      *   BOOL DisableAllPrivileges
 849      *   PTOKEN_PRIVILEGES NewState
 850      *   DWORD BufferLength
 851      *   PTOKEN_PRIVILEGES
 852      *   PDWORD ReturnLength
 853      * )
 854      */
 855     static native void AdjustTokenPrivileges(long token, long luid, int attributes)
 856         throws WindowsException;
 857 
 858 
 859     /**
 860      * AccessCheck(
 861      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
 862      *   HANDLE ClientToken,
 863      *   DWORD DesiredAccess,
 864      *   PGENERIC_MAPPING GenericMapping,
 865      *   PPRIVILEGE_SET PrivilegeSet,
 866      *   LPDWORD PrivilegeSetLength,
 867      *   LPDWORD GrantedAccess,
 868      *   LPBOOL AccessStatus
 869      * )
 870      */
 871     static native boolean AccessCheck(long token, long securityInfo, int accessMask,
 872         int genericRead, int genericWrite, int genericExecute, int genericAll)
 873         throws WindowsException;
 874 
 875     /**
 876      */
 877     static long LookupPrivilegeValue(String name) throws WindowsException {
 878         NativeBuffer buffer = asNativeBuffer(name);
 879         try {
 880             return LookupPrivilegeValue0(buffer.address());
 881         } finally {
 882             buffer.release();
 883         }
 884     }
 885     private static native long LookupPrivilegeValue0(long lpName)
 886         throws WindowsException;
 887 
 888     /**
 889      * CreateSymbolicLink(
 890      *   LPCWSTR lpSymlinkFileName,
 891      *   LPCWSTR lpTargetFileName,
 892      *   DWORD dwFlags
 893      * )
 894      */
 895     static void CreateSymbolicLink(String link, String target, int flags)
 896         throws WindowsException
 897     {
 898         NativeBuffer linkBuffer = asNativeBuffer(link);
 899         NativeBuffer targetBuffer = asNativeBuffer(target);
 900         try {
 901             CreateSymbolicLink0(linkBuffer.address(), targetBuffer.address(),
 902                                 flags);
 903         } finally {
 904             targetBuffer.release();
 905             linkBuffer.release();
 906         }
 907     }
 908     private static native void CreateSymbolicLink0(long linkAddress,
 909         long targetAddress, int flags) throws WindowsException;
 910 
 911     /**
 912      * CreateHardLink(
 913      *    LPCTSTR lpFileName,
 914      *    LPCTSTR lpExistingFileName,
 915      *    LPSECURITY_ATTRIBUTES lpSecurityAttributes
 916      * )
 917      */
 918     static void CreateHardLink(String newFile, String existingFile)
 919         throws WindowsException
 920     {
 921         NativeBuffer newFileBuffer = asNativeBuffer(newFile);
 922         NativeBuffer existingFileBuffer = asNativeBuffer(existingFile);
 923         try {
 924             CreateHardLink0(newFileBuffer.address(), existingFileBuffer.address());
 925         } finally {
 926             existingFileBuffer.release();
 927             newFileBuffer.release();
 928         }
 929     }
 930     private static native void CreateHardLink0(long newFileBuffer,
 931         long existingFileBuffer) throws WindowsException;
 932 
 933     /**
 934      * GetFullPathName(
 935      *   LPCTSTR lpFileName,
 936      *   DWORD nBufferLength,
 937      *   LPTSTR lpBuffer,
 938      *   LPTSTR *lpFilePart
 939      * )
 940      */
 941     static String GetFullPathName(String path) throws WindowsException {
 942         NativeBuffer buffer = asNativeBuffer(path);
 943         try {
 944             return GetFullPathName0(buffer.address());
 945         } finally {
 946             buffer.release();
 947         }
 948     }
 949     private static native String GetFullPathName0(long pathAddress)
 950         throws WindowsException;
 951 
 952     /**
 953      * GetFinalPathNameByHandle(
 954      *   HANDLE hFile,
 955      *   LPTSTR lpszFilePath,
 956      *   DWORD cchFilePath,
 957      *   DWORD dwFlags
 958      * )
 959      */
 960     static native String GetFinalPathNameByHandle(long handle)
 961         throws WindowsException;
 962 
 963     /**
 964      * FormatMessage(
 965      *   DWORD dwFlags,
 966      *   LPCVOID lpSource,
 967      *   DWORD dwMessageId,
 968      *   DWORD dwLanguageId,
 969      *   LPTSTR lpBuffer,
 970      *   DWORD nSize,
 971      *   va_list *Arguments
 972      * )
 973      */
 974     static native String FormatMessage(int errorCode);
 975 
 976     /**
 977      * LocalFree(
 978      *   HLOCAL hMem
 979      * )
 980      */
 981     static native void LocalFree(long address);
 982 
 983     /**
 984      * HANDLE CreateIoCompletionPort (
 985      *   HANDLE FileHandle,
 986      *   HANDLE ExistingCompletionPort,
 987      *   ULONG_PTR CompletionKey,
 988      *   DWORD NumberOfConcurrentThreads
 989      * )
 990      */
 991     static native long CreateIoCompletionPort(long fileHandle, long existingPort,
 992         long completionKey) throws WindowsException;
 993 
 994 
 995     /**
 996      * GetQueuedCompletionStatus(
 997      *   HANDLE CompletionPort,
 998      *   LPDWORD lpNumberOfBytesTransferred,
 999      *   PULONG_PTR lpCompletionKey,
1000      *   LPOVERLAPPED *lpOverlapped,
1001      *   DWORD dwMilliseconds
1002      */
1003     static CompletionStatus GetQueuedCompletionStatus(long completionPort)
1004         throws WindowsException
1005     {
1006         CompletionStatus status = new CompletionStatus();
1007         GetQueuedCompletionStatus0(completionPort, status);
1008         return status;
1009     }
1010     static class CompletionStatus {
1011         private int error;
1012         private int bytesTransferred;
1013         private long completionKey;
1014         private CompletionStatus() { }
1015 
1016         int error() { return error; }
1017         int bytesTransferred() { return bytesTransferred; }
1018         long completionKey() { return completionKey; }
1019     }
1020     private static native void GetQueuedCompletionStatus0(long completionPort,
1021         CompletionStatus status) throws WindowsException;
1022 
1023     /**
1024      * PostQueuedCompletionStatus(
1025      *   HANDLE CompletionPort,
1026      *   DWORD dwNumberOfBytesTransferred,
1027      *   ULONG_PTR dwCompletionKey,
1028      *   LPOVERLAPPED lpOverlapped
1029      * )
1030      */
1031     static native void PostQueuedCompletionStatus(long completionPort,
1032         long completionKey) throws WindowsException;
1033 
1034     /**
1035      * ReadDirectoryChangesW(
1036      *   HANDLE hDirectory,
1037      *   LPVOID lpBuffer,
1038      *   DWORD nBufferLength,
1039      *   BOOL bWatchSubtree,
1040      *   DWORD dwNotifyFilter,
1041      *   LPDWORD lpBytesReturned,
1042      *   LPOVERLAPPED lpOverlapped,
1043      *   LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
1044      * )
1045      */
1046     static native void ReadDirectoryChangesW(long hDirectory,
1047                                              long bufferAddress,
1048                                              int bufferLength,
1049                                              boolean watchSubTree,
1050                                              int filter,
1051                                              long bytesReturnedAddress,
1052                                              long pOverlapped)
1053         throws WindowsException;
1054 
1055 
1056     /**
1057      * CancelIo(
1058      *   HANDLE hFile
1059      * )
1060      */
1061     static native void CancelIo(long hFile) throws WindowsException;
1062 
1063     /**
1064      * GetOverlappedResult(
1065      *   HANDLE hFile,
1066      *   LPOVERLAPPED lpOverlapped,
1067      *   LPDWORD lpNumberOfBytesTransferred,
1068      *   BOOL bWait
1069      * );
1070      */
1071     static native int GetOverlappedResult(long hFile, long lpOverlapped)
1072         throws WindowsException;
1073 
1074     /**
1075      * BackupRead(
1076      *   HANDLE hFile,
1077      *   LPBYTE lpBuffer,
1078      *   DWORD nNumberOfBytesToRead,
1079      *   LPDWORD lpNumberOfBytesRead,
1080      *   BOOL bAbort,
1081      *   BOOL bProcessSecurity,
1082      *   LPVOID* lpContext
1083      * )
1084      */
1085     static BackupResult BackupRead(long hFile,
1086                                    long bufferAddress,
1087                                    int bufferSize,
1088                                    boolean abort,
1089                                    long context)
1090         throws WindowsException
1091     {
1092         BackupResult result = new BackupResult();
1093         BackupRead0(hFile, bufferAddress, bufferSize, abort, context, result);
1094         return result;
1095     }
1096     static class BackupResult {
1097         private int bytesTransferred;
1098         private long context;
1099         private BackupResult() { }
1100 
1101         int bytesTransferred() { return bytesTransferred; }
1102         long context() { return context; }
1103     }
1104     private static native void BackupRead0(long hFile, long bufferAddress,
1105         int bufferSize, boolean abort, long context, BackupResult result)
1106         throws WindowsException;
1107 
1108     /**
1109      * BackupSeek(
1110      *   HANDLE hFile,
1111      *   DWORD dwLowBytesToSeek,
1112      *   DWORD dwHighBytesToSeek,
1113      *   LPDWORD lpdwLowByteSeeked,
1114      *   LPDWORD lpdwHighByteSeeked,
1115      *   LPVOID* lpContext
1116      * )
1117      */
1118     static native void BackupSeek(long hFile, long bytesToSeek, long context)
1119         throws WindowsException;
1120 
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         AccessController.doPrivileged(new PrivilegedAction<Void>() {
1155             public Void run() {
1156                 // nio.dll has dependency on net.dll
1157                 System.loadLibrary("net");
1158                 System.loadLibrary("nio");
1159                 return null;
1160         }});
1161         initIDs();
1162     }
1163 
1164 }