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