1 /*
2  * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.nio.fs;
27 
28 import java.security.AccessController;
29 import java.security.PrivilegedAction;
30 import jdk.internal.misc.Unsafe;
31 
32 /**
33  * Win32 and library calls.
34  */
35 
36 class WindowsNativeDispatcher {
WindowsNativeDispatcher()37     private WindowsNativeDispatcher() { }
38 
39     /**
40      * HANDLE CreateEvent(
41      *   LPSECURITY_ATTRIBUTES lpEventAttributes,
42      *   BOOL bManualReset,
43      *   BOOL bInitialState,
44      *   PCTSTR lpName
45      * );
46      */
CreateEvent(boolean bManualReset, boolean bInitialState)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      */
CreateFile(String path, int dwDesiredAccess, int dwShareMode, long lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes)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     }
CreateFile(String path, int dwDesiredAccess, int dwShareMode, int dwCreationDisposition, int dwFlagsAndAttributes)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     }
CreateFile0(long lpFileName, int dwDesiredAccess, int dwShareMode, long lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes)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      */
CloseHandle(long handle)104     static native void CloseHandle(long handle);
105 
106     /**
107      * DeleteFile(
108      *   LPCTSTR lpFileName
109      * )
110      */
DeleteFile(String path)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     }
DeleteFile0(long lpFileName)119     private static native void DeleteFile0(long lpFileName)
120         throws WindowsException;
121 
122     /**
123      * CreateDirectory(
124      *   LPCTSTR lpPathName,
125      *   LPSECURITY_ATTRIBUTES lpSecurityAttributes
126      * )
127      */
CreateDirectory(String path, long lpSecurityAttributes)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     }
CreateDirectory0(long lpFileName, long lpSecurityAttributes)136     private static native void CreateDirectory0(long lpFileName, long lpSecurityAttributes)
137         throws WindowsException;
138 
139     /**
140      * RemoveDirectory(
141      *   LPCTSTR lpPathName
142      * )
143      */
RemoveDirectory(String path)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     }
RemoveDirectory0(long lpFileName)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      */
DeviceIoControlSetSparse(long handle)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      */
DeviceIoControlGetReparsePoint(long handle, long bufferAddress, int bufferSize)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      */
FindFirstFile(String path)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 
FirstFile()196         private FirstFile() { }
handle()197         public long handle()    { return handle; }
name()198         public String name()    { return name; }
attributes()199         public int attributes() { return attributes; }
200     }
FindFirstFile0(long lpFileName, FirstFile obj)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      */
FindFirstFile(String path, long address)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     }
FindFirstFile1(long lpFileName, long address)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      */
FindNextFile(long handle, long address)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      */
FindFirstStream(String path)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 
FirstStream()256         private FirstStream() { }
handle()257         public long handle()    { return handle; }
name()258         public String name()    { return name; }
259     }
FindFirstStream0(long lpFileName, FirstStream obj)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      */
FindNextStream(long handle)269     static native String FindNextStream(long handle) throws WindowsException;
270 
271     /**
272      * FindClose(
273      *   HANDLE hFindFile
274      * )
275      */
FindClose(long handle)276     static native void FindClose(long handle) throws WindowsException;
277 
278     /**
279      * GetFileInformationByHandle(
280      *   HANDLE hFile,
281      *   LPBY_HANDLE_FILE_INFORMATION lpFileInformation
282      * )
283      */
GetFileInformationByHandle(long handle, long address)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      */
CopyFileEx(String source, String target, int flags, long addressToPollForCancel)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     }
CopyFileEx0(long existingAddress, long newAddress, int flags, long addressToPollForCancel)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      */
MoveFileEx(String source, String target, int flags)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     }
MoveFileEx0(long existingAddress, long newAddress, int flags)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      */
GetFileAttributes(String path)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     }
GetFileAttributes0(long lpFileName)349     private static native int GetFileAttributes0(long lpFileName)
350         throws WindowsException;
351 
352     /**
353      * SetFileAttributes(
354      *   LPCTSTR lpFileName,
355      *   DWORD dwFileAttributes
356      */
SetFileAttributes(String path, int dwFileAttributes)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     }
SetFileAttributes0(long lpFileName, int dwFileAttributes)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      */
GetFileAttributesEx(String path, long address)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     }
GetFileAttributesEx0(long lpFileName, long address)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      */
SetFileTime(long handle, long createTime, long lastAccessTime, long lastWriteTime)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      */
SetEndOfFile(long handle)406     static native void SetEndOfFile(long handle) throws WindowsException;
407 
408     /**
409      * DWORD GetLogicalDrives(VOID)
410      */
GetLogicalDrives()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      */
GetVolumeInformation(String root)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;
VolumeInformation()442         private VolumeInformation() { }
443 
fileSystemName()444         public String fileSystemName()      { return fileSystemName; }
volumeName()445         public String volumeName()          { return volumeName; }
volumeSerialNumber()446         public int volumeSerialNumber()     { return volumeSerialNumber; }
flags()447         public int flags()                  { return flags; }
448     }
GetVolumeInformation0(long lpRoot, VolumeInformation obj)449     private static native void GetVolumeInformation0(long lpRoot,
450                                                      VolumeInformation obj)
451         throws WindowsException;
452 
453     /**
454      * UINT GetDriveType(
455      *   LPCTSTR lpRootPathName
456      * )
457      */
GetDriveType(String root)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     }
GetDriveType0(long lpRoot)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      */
GetDiskFreeSpaceEx(String path)476     static DiskFreeSpace GetDiskFreeSpaceEx(String path)
477         throws WindowsException
478     {
479         NativeBuffer buffer = asNativeBuffer(path);
480         try {
481             DiskFreeSpace space = new DiskFreeSpace();
482             GetDiskFreeSpaceEx0(buffer.address(), space);
483             return space;
484         } finally {
485             buffer.release();
486         }
487     }
488 
489     /**
490      * GetDiskFreeSpace(
491      *   LPCTSTR lpRootPathName,
492      *   LPDWORD lpSectorsPerCluster,
493      *   LPDWORD lpBytesPerSector,
494      *   LPDWORD lpNumberOfFreeClusters,
495      *   LPDWORD lpTotalNumberOfClusters
496      * )
497      */
GetDiskFreeSpace(String path)498     static DiskFreeSpace GetDiskFreeSpace(String path)
499         throws WindowsException
500     {
501         NativeBuffer buffer = asNativeBuffer(path);
502         try {
503             DiskFreeSpace space = new DiskFreeSpace();
504             GetDiskFreeSpace0(buffer.address(), space);
505             return space;
506         } finally {
507             buffer.release();
508         }
509     }
510 
511     static class DiskFreeSpace {
512         private long freeBytesAvailable;
513         private long totalNumberOfBytes;
514         private long totalNumberOfFreeBytes;
515         private long bytesPerSector;
DiskFreeSpace()516         private DiskFreeSpace() { }
517 
freeBytesAvailable()518         public long freeBytesAvailable()      { return freeBytesAvailable; }
totalNumberOfBytes()519         public long totalNumberOfBytes()      { return totalNumberOfBytes; }
totalNumberOfFreeBytes()520         public long totalNumberOfFreeBytes()  { return totalNumberOfFreeBytes; }
bytesPerSector()521         public long bytesPerSector()          { return bytesPerSector; }
522     }
GetDiskFreeSpaceEx0(long lpDirectoryName, DiskFreeSpace obj)523     private static native void GetDiskFreeSpaceEx0(long lpDirectoryName,
524                                                    DiskFreeSpace obj)
525         throws WindowsException;
526 
527 
GetDiskFreeSpace0(long lpRootPathName, DiskFreeSpace obj)528     private static native void GetDiskFreeSpace0(long lpRootPathName,
529                                                  DiskFreeSpace obj)
530         throws WindowsException;
531 
532     /**
533      * GetVolumePathName(
534      *   LPCTSTR lpszFileName,
535      *   LPTSTR lpszVolumePathName,
536      *   DWORD cchBufferLength
537      * )
538      *
539      * @return  lpFileName
540      */
GetVolumePathName(String path)541     static String GetVolumePathName(String path) throws WindowsException {
542         NativeBuffer buffer = asNativeBuffer(path);
543         try {
544             return GetVolumePathName0(buffer.address());
545         } finally {
546             buffer.release();
547         }
548     }
GetVolumePathName0(long lpFileName)549     private static native String GetVolumePathName0(long lpFileName)
550         throws WindowsException;
551 
552 
553     /**
554      * InitializeSecurityDescriptor(
555      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
556      *   DWORD dwRevision
557      * )
558      */
InitializeSecurityDescriptor(long sdAddress)559     static native void InitializeSecurityDescriptor(long sdAddress)
560         throws WindowsException;
561 
562     /**
563      * InitializeAcl(
564      *   PACL pAcl,
565      *   DWORD nAclLength,
566      *   DWORD dwAclRevision
567      * )
568      */
InitializeAcl(long aclAddress, int size)569     static native void InitializeAcl(long aclAddress, int size)
570          throws WindowsException;
571 
572     /**
573      * GetFileSecurity(
574      *   LPCTSTR lpFileName,
575      *   SECURITY_INFORMATION RequestedInformation,
576      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
577      *   DWORD nLength,
578      *   LPDWORD lpnLengthNeeded
579      * )
580      */
GetFileSecurity(String path, int requestedInformation, long pSecurityDescriptor, int nLength)581     static int GetFileSecurity(String path,
582                                int requestedInformation,
583                                long pSecurityDescriptor,
584                                int nLength) throws WindowsException
585     {
586         NativeBuffer buffer = asNativeBuffer(path);
587         try {
588             return GetFileSecurity0(buffer.address(), requestedInformation,
589                 pSecurityDescriptor, nLength);
590         } finally {
591             buffer.release();
592         }
593     }
GetFileSecurity0(long lpFileName, int requestedInformation, long pSecurityDescriptor, int nLength)594     private static native int GetFileSecurity0(long lpFileName,
595                                                int requestedInformation,
596                                                long pSecurityDescriptor,
597                                                int nLength) throws WindowsException;
598 
599     /**
600      * SetFileSecurity(
601      *   LPCTSTR lpFileName,
602      *   SECURITY_INFORMATION SecurityInformation,
603      *   PSECURITY_DESCRIPTOR pSecurityDescriptor
604      * )
605      */
SetFileSecurity(String path, int securityInformation, long pSecurityDescriptor)606     static void SetFileSecurity(String path,
607                                 int securityInformation,
608                                 long pSecurityDescriptor)
609         throws WindowsException
610     {
611         NativeBuffer buffer = asNativeBuffer(path);
612         try {
613             SetFileSecurity0(buffer.address(), securityInformation,
614                 pSecurityDescriptor);
615         } finally {
616             buffer.release();
617         }
618     }
SetFileSecurity0(long lpFileName, int securityInformation, long pSecurityDescriptor)619     static native void SetFileSecurity0(long lpFileName, int securityInformation,
620         long pSecurityDescriptor) throws WindowsException;
621 
622     /**
623      * GetSecurityDescriptorOwner(
624      *   PSECURITY_DESCRIPTOR pSecurityDescriptor
625      *   PSID *pOwner,
626      *   LPBOOL lpbOwnerDefaulted
627      * )
628      *
629      * @return  pOwner
630      */
GetSecurityDescriptorOwner(long pSecurityDescriptor)631     static native long GetSecurityDescriptorOwner(long pSecurityDescriptor)
632         throws WindowsException;
633 
634     /**
635      * SetSecurityDescriptorOwner(
636      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
637      *   PSID pOwner,
638      *   BOOL bOwnerDefaulted
639      * )
640      */
SetSecurityDescriptorOwner(long pSecurityDescriptor, long pOwner)641     static native void SetSecurityDescriptorOwner(long pSecurityDescriptor,
642                                                   long pOwner)
643         throws WindowsException;
644 
645     /**
646      * GetSecurityDescriptorDacl(
647      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
648      *   LPBOOL lpbDaclPresent,
649      *   PACL *pDacl,
650      *   LPBOOL lpbDaclDefaulted
651      * )
652      */
GetSecurityDescriptorDacl(long pSecurityDescriptor)653     static native long GetSecurityDescriptorDacl(long pSecurityDescriptor);
654 
655     /**
656      * SetSecurityDescriptorDacl(
657      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
658      *   BOOL bDaclPresent,
659      *   PACL pDacl,
660      *   BOOL bDaclDefaulted
661      * )
662      */
SetSecurityDescriptorDacl(long pSecurityDescriptor, long pAcl)663     static native void SetSecurityDescriptorDacl(long pSecurityDescriptor, long pAcl)
664         throws WindowsException;
665 
666 
667     /**
668      * GetAclInformation(
669      *   PACL pAcl,
670      *   LPVOID pAclInformation,
671      *   DWORD nAclInformationLength,
672      *   ACL_INFORMATION_CLASS dwAclInformationClass
673      * )
674      */
GetAclInformation(long aclAddress)675     static AclInformation GetAclInformation(long aclAddress) {
676         AclInformation info = new AclInformation();
677         GetAclInformation0(aclAddress, info);
678         return info;
679     }
680     static class AclInformation {
681         private int aceCount;
AclInformation()682         private AclInformation() { }
683 
aceCount()684         public int aceCount()   { return aceCount; }
685     }
GetAclInformation0(long aclAddress, AclInformation obj)686     private static native void GetAclInformation0(long aclAddress,
687         AclInformation obj);
688 
689     /**
690      * GetAce(
691      *   PACL pAcl,
692      *   DWORD dwAceIndex,
693      *   LPVOID *pAce
694      * )
695      */
GetAce(long aclAddress, int aceIndex)696     static native long GetAce(long aclAddress, int aceIndex);
697 
698     /**
699      * AddAccessAllowedAceEx(
700      *   PACL pAcl,
701      *   DWORD dwAceRevision,
702      *   DWORD AceFlags,
703      *   DWORD AccessMask,
704      *   PSID pSid
705      * )
706      */
AddAccessAllowedAceEx(long aclAddress, int flags, int mask, long sidAddress)707     static native void AddAccessAllowedAceEx(long aclAddress, int flags,
708         int mask, long sidAddress) throws WindowsException;
709 
710     /**
711      * AddAccessDeniedAceEx(
712      *   PACL pAcl,
713      *   DWORD dwAceRevision,
714      *   DWORD AceFlags,
715      *   DWORD AccessMask,
716      *   PSID pSid
717      * )
718      */
AddAccessDeniedAceEx(long aclAddress, int flags, int mask, long sidAddress)719     static native void AddAccessDeniedAceEx(long aclAddress, int flags,
720         int mask, long sidAddress) throws WindowsException;
721 
722     /**
723      * LookupAccountSid(
724      *   LPCTSTR lpSystemName,
725      *   PSID Sid,
726      *   LPTSTR Name,
727      *   LPDWORD cbName,
728      *   LPTSTR ReferencedDomainName,
729      *   LPDWORD cbReferencedDomainName,
730      *   PSID_NAME_USE peUse
731      * )
732      */
LookupAccountSid(long sidAddress)733     static Account LookupAccountSid(long sidAddress) throws WindowsException {
734         Account acc = new Account();
735         LookupAccountSid0(sidAddress, acc);
736         return acc;
737     }
738     static class Account {
739         private String domain;
740         private String name;
741         private int use;
Account()742         private Account() { }
743 
domain()744         public String domain()  { return domain; }
name()745         public String name()    { return name; }
use()746         public int use()        { return use; }
747     }
LookupAccountSid0(long sidAddress, Account obj)748     private static native void LookupAccountSid0(long sidAddress, Account obj)
749         throws WindowsException;
750 
751     /**
752      * LookupAccountName(
753      *   LPCTSTR lpSystemName,
754      *   LPCTSTR lpAccountName,
755      *   PSID Sid,
756      *   LPDWORD cbSid,
757      *   LPTSTR ReferencedDomainName,
758      *   LPDWORD cbReferencedDomainName,
759      *   PSID_NAME_USE peUse
760      * )
761      *
762      * @return  cbSid
763      */
LookupAccountName(String accountName, long pSid, int cbSid)764     static int LookupAccountName(String accountName,
765                                  long pSid,
766                                  int cbSid) throws WindowsException
767     {
768         NativeBuffer buffer = asNativeBuffer(accountName);
769         try {
770             return LookupAccountName0(buffer.address(), pSid, cbSid);
771         } finally {
772             buffer.release();
773         }
774     }
LookupAccountName0(long lpAccountName, long pSid, int cbSid)775     private static native int LookupAccountName0(long lpAccountName, long pSid,
776         int cbSid) throws WindowsException;
777 
778     /**
779      * DWORD GetLengthSid(
780      *   PSID pSid
781      * )
782      */
GetLengthSid(long sidAddress)783     static native int GetLengthSid(long sidAddress);
784 
785     /**
786      * ConvertSidToStringSid(
787      *   PSID Sid,
788      *   LPTSTR* StringSid
789      * )
790      *
791      * @return  StringSid
792      */
ConvertSidToStringSid(long sidAddress)793     static native String ConvertSidToStringSid(long sidAddress)
794         throws WindowsException;
795 
796     /**
797      * ConvertStringSidToSid(
798      *   LPCTSTR StringSid,
799      *   PSID* pSid
800      * )
801      *
802      * @return  pSid
803      */
ConvertStringSidToSid(String sidString)804     static long ConvertStringSidToSid(String sidString)
805         throws WindowsException
806     {
807         NativeBuffer buffer = asNativeBuffer(sidString);
808         try {
809             return ConvertStringSidToSid0(buffer.address());
810         } finally {
811             buffer.release();
812         }
813     }
ConvertStringSidToSid0(long lpStringSid)814     private static native long ConvertStringSidToSid0(long lpStringSid)
815         throws WindowsException;
816 
817     /**
818      * HANDLE GetCurrentProcess(VOID)
819      */
GetCurrentProcess()820     static native long GetCurrentProcess();
821 
822     /**
823      * HANDLE GetCurrentThread(VOID)
824      */
GetCurrentThread()825     static native long GetCurrentThread();
826 
827     /**
828      * OpenProcessToken(
829      *   HANDLE ProcessHandle,
830      *   DWORD DesiredAccess,
831      *   PHANDLE TokenHandle
832      * )
833      */
OpenProcessToken(long hProcess, int desiredAccess)834     static native long OpenProcessToken(long hProcess, int desiredAccess)
835         throws WindowsException;
836 
837     /**
838      * OpenThreadToken(
839      *   HANDLE ThreadHandle,
840      *   DWORD DesiredAccess,
841      *   BOOL OpenAsSelf,
842      *   PHANDLE TokenHandle
843      * )
844      */
OpenThreadToken(long hThread, int desiredAccess, boolean openAsSelf)845     static native long OpenThreadToken(long hThread, int desiredAccess,
846         boolean openAsSelf) throws WindowsException;
847 
848     /**
849      */
DuplicateTokenEx(long hThread, int desiredAccess)850     static native long DuplicateTokenEx(long hThread, int desiredAccess)
851         throws WindowsException;
852 
853     /**
854      * SetThreadToken(
855      *   PHANDLE Thread,
856      *   HANDLE Token
857      * )
858      */
SetThreadToken(long thread, long hToken)859     static native void SetThreadToken(long thread, long hToken)
860         throws WindowsException;
861 
862     /**
863      * GetTokenInformation(
864      *   HANDLE TokenHandle,
865      *   TOKEN_INFORMATION_CLASS TokenInformationClass,
866      *   LPVOID TokenInformation,
867      *   DWORD TokenInformationLength,
868      *   PDWORD ReturnLength
869      * )
870      */
GetTokenInformation(long token, int tokenInfoClass, long pTokenInfo, int tokenInfoLength)871     static native int GetTokenInformation(long token, int tokenInfoClass,
872         long pTokenInfo, int tokenInfoLength) throws WindowsException;
873 
874     /**
875      * AdjustTokenPrivileges(
876      *   HANDLE TokenHandle,
877      *   BOOL DisableAllPrivileges
878      *   PTOKEN_PRIVILEGES NewState
879      *   DWORD BufferLength
880      *   PTOKEN_PRIVILEGES
881      *   PDWORD ReturnLength
882      * )
883      */
AdjustTokenPrivileges(long token, long luid, int attributes)884     static native void AdjustTokenPrivileges(long token, long luid, int attributes)
885         throws WindowsException;
886 
887 
888     /**
889      * AccessCheck(
890      *   PSECURITY_DESCRIPTOR pSecurityDescriptor,
891      *   HANDLE ClientToken,
892      *   DWORD DesiredAccess,
893      *   PGENERIC_MAPPING GenericMapping,
894      *   PPRIVILEGE_SET PrivilegeSet,
895      *   LPDWORD PrivilegeSetLength,
896      *   LPDWORD GrantedAccess,
897      *   LPBOOL AccessStatus
898      * )
899      */
AccessCheck(long token, long securityInfo, int accessMask, int genericRead, int genericWrite, int genericExecute, int genericAll)900     static native boolean AccessCheck(long token, long securityInfo, int accessMask,
901         int genericRead, int genericWrite, int genericExecute, int genericAll)
902         throws WindowsException;
903 
904     /**
905      */
LookupPrivilegeValue(String name)906     static long LookupPrivilegeValue(String name) throws WindowsException {
907         NativeBuffer buffer = asNativeBuffer(name);
908         try {
909             return LookupPrivilegeValue0(buffer.address());
910         } finally {
911             buffer.release();
912         }
913     }
LookupPrivilegeValue0(long lpName)914     private static native long LookupPrivilegeValue0(long lpName)
915         throws WindowsException;
916 
917     /**
918      * CreateSymbolicLink(
919      *   LPCWSTR lpSymlinkFileName,
920      *   LPCWSTR lpTargetFileName,
921      *   DWORD dwFlags
922      * )
923      */
CreateSymbolicLink(String link, String target, int flags)924     static void CreateSymbolicLink(String link, String target, int flags)
925         throws WindowsException
926     {
927         NativeBuffer linkBuffer = asNativeBuffer(link);
928         NativeBuffer targetBuffer = asNativeBuffer(target);
929         try {
930             CreateSymbolicLink0(linkBuffer.address(), targetBuffer.address(),
931                                 flags);
932         } finally {
933             targetBuffer.release();
934             linkBuffer.release();
935         }
936     }
CreateSymbolicLink0(long linkAddress, long targetAddress, int flags)937     private static native void CreateSymbolicLink0(long linkAddress,
938         long targetAddress, int flags) throws WindowsException;
939 
940     /**
941      * CreateHardLink(
942      *    LPCTSTR lpFileName,
943      *    LPCTSTR lpExistingFileName,
944      *    LPSECURITY_ATTRIBUTES lpSecurityAttributes
945      * )
946      */
CreateHardLink(String newFile, String existingFile)947     static void CreateHardLink(String newFile, String existingFile)
948         throws WindowsException
949     {
950         NativeBuffer newFileBuffer = asNativeBuffer(newFile);
951         NativeBuffer existingFileBuffer = asNativeBuffer(existingFile);
952         try {
953             CreateHardLink0(newFileBuffer.address(), existingFileBuffer.address());
954         } finally {
955             existingFileBuffer.release();
956             newFileBuffer.release();
957         }
958     }
CreateHardLink0(long newFileBuffer, long existingFileBuffer)959     private static native void CreateHardLink0(long newFileBuffer,
960         long existingFileBuffer) throws WindowsException;
961 
962     /**
963      * GetFullPathName(
964      *   LPCTSTR lpFileName,
965      *   DWORD nBufferLength,
966      *   LPTSTR lpBuffer,
967      *   LPTSTR *lpFilePart
968      * )
969      */
GetFullPathName(String path)970     static String GetFullPathName(String path) throws WindowsException {
971         NativeBuffer buffer = asNativeBuffer(path);
972         try {
973             return GetFullPathName0(buffer.address());
974         } finally {
975             buffer.release();
976         }
977     }
GetFullPathName0(long pathAddress)978     private static native String GetFullPathName0(long pathAddress)
979         throws WindowsException;
980 
981     /**
982      * GetFinalPathNameByHandle(
983      *   HANDLE hFile,
984      *   LPTSTR lpszFilePath,
985      *   DWORD cchFilePath,
986      *   DWORD dwFlags
987      * )
988      */
GetFinalPathNameByHandle(long handle)989     static native String GetFinalPathNameByHandle(long handle)
990         throws WindowsException;
991 
992     /**
993      * FormatMessage(
994      *   DWORD dwFlags,
995      *   LPCVOID lpSource,
996      *   DWORD dwMessageId,
997      *   DWORD dwLanguageId,
998      *   LPTSTR lpBuffer,
999      *   DWORD nSize,
1000      *   va_list *Arguments
1001      * )
1002      */
FormatMessage(int errorCode)1003     static native String FormatMessage(int errorCode);
1004 
1005     /**
1006      * LocalFree(
1007      *   HLOCAL hMem
1008      * )
1009      */
LocalFree(long address)1010     static native void LocalFree(long address);
1011 
1012     /**
1013      * HANDLE CreateIoCompletionPort (
1014      *   HANDLE FileHandle,
1015      *   HANDLE ExistingCompletionPort,
1016      *   ULONG_PTR CompletionKey,
1017      *   DWORD NumberOfConcurrentThreads
1018      * )
1019      */
CreateIoCompletionPort(long fileHandle, long existingPort, long completionKey)1020     static native long CreateIoCompletionPort(long fileHandle, long existingPort,
1021         long completionKey) throws WindowsException;
1022 
1023 
1024     /**
1025      * GetQueuedCompletionStatus(
1026      *   HANDLE CompletionPort,
1027      *   LPDWORD lpNumberOfBytesTransferred,
1028      *   PULONG_PTR lpCompletionKey,
1029      *   LPOVERLAPPED *lpOverlapped,
1030      *   DWORD dwMilliseconds
1031      */
GetQueuedCompletionStatus(long completionPort)1032     static CompletionStatus GetQueuedCompletionStatus(long completionPort)
1033         throws WindowsException
1034     {
1035         CompletionStatus status = new CompletionStatus();
1036         GetQueuedCompletionStatus0(completionPort, status);
1037         return status;
1038     }
1039     static class CompletionStatus {
1040         private int error;
1041         private int bytesTransferred;
1042         private long completionKey;
CompletionStatus()1043         private CompletionStatus() { }
1044 
error()1045         int error() { return error; }
bytesTransferred()1046         int bytesTransferred() { return bytesTransferred; }
completionKey()1047         long completionKey() { return completionKey; }
1048     }
GetQueuedCompletionStatus0(long completionPort, CompletionStatus status)1049     private static native void GetQueuedCompletionStatus0(long completionPort,
1050         CompletionStatus status) throws WindowsException;
1051 
1052     /**
1053      * PostQueuedCompletionStatus(
1054      *   HANDLE CompletionPort,
1055      *   DWORD dwNumberOfBytesTransferred,
1056      *   ULONG_PTR dwCompletionKey,
1057      *   LPOVERLAPPED lpOverlapped
1058      * )
1059      */
PostQueuedCompletionStatus(long completionPort, long completionKey)1060     static native void PostQueuedCompletionStatus(long completionPort,
1061         long completionKey) throws WindowsException;
1062 
1063     /**
1064      * ReadDirectoryChangesW(
1065      *   HANDLE hDirectory,
1066      *   LPVOID lpBuffer,
1067      *   DWORD nBufferLength,
1068      *   BOOL bWatchSubtree,
1069      *   DWORD dwNotifyFilter,
1070      *   LPDWORD lpBytesReturned,
1071      *   LPOVERLAPPED lpOverlapped,
1072      *   LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
1073      * )
1074      */
ReadDirectoryChangesW(long hDirectory, long bufferAddress, int bufferLength, boolean watchSubTree, int filter, long bytesReturnedAddress, long pOverlapped)1075     static native void ReadDirectoryChangesW(long hDirectory,
1076                                              long bufferAddress,
1077                                              int bufferLength,
1078                                              boolean watchSubTree,
1079                                              int filter,
1080                                              long bytesReturnedAddress,
1081                                              long pOverlapped)
1082         throws WindowsException;
1083 
1084 
1085     /**
1086      * CancelIo(
1087      *   HANDLE hFile
1088      * )
1089      */
CancelIo(long hFile)1090     static native void CancelIo(long hFile) throws WindowsException;
1091 
1092     /**
1093      * GetOverlappedResult(
1094      *   HANDLE hFile,
1095      *   LPOVERLAPPED lpOverlapped,
1096      *   LPDWORD lpNumberOfBytesTransferred,
1097      *   BOOL bWait
1098      * );
1099      */
GetOverlappedResult(long hFile, long lpOverlapped)1100     static native int GetOverlappedResult(long hFile, long lpOverlapped)
1101         throws WindowsException;
1102 
1103     // -- support for copying String with a NativeBuffer --
1104 
1105     private static final Unsafe unsafe = Unsafe.getUnsafe();
1106 
asNativeBuffer(String s)1107     static NativeBuffer asNativeBuffer(String s) throws WindowsException {
1108         if (s.length() > (Integer.MAX_VALUE - 2)/2) {
1109             throw new WindowsException
1110                 ("String too long to convert to native buffer");
1111         }
1112 
1113         int stringLengthInBytes = s.length() << 1;
1114         int sizeInBytes = stringLengthInBytes + 2;  // char terminator
1115 
1116         // get a native buffer of sufficient size
1117         NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(sizeInBytes);
1118         if (buffer == null) {
1119             buffer = NativeBuffers.allocNativeBuffer(sizeInBytes);
1120         } else {
1121             // buffer already contains the string contents
1122             if (buffer.owner() == s)
1123                 return buffer;
1124         }
1125 
1126         // copy into buffer and zero terminate
1127         char[] chars = s.toCharArray();
1128         unsafe.copyMemory(chars, Unsafe.ARRAY_CHAR_BASE_OFFSET, null,
1129             buffer.address(), (long)stringLengthInBytes);
1130         unsafe.putChar(buffer.address() + stringLengthInBytes, (char)0);
1131         buffer.setOwner(s);
1132         return buffer;
1133     }
1134 
1135     // -- native library initialization --
1136 
initIDs()1137     private static native void initIDs();
1138 
1139     static {
AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { System.loadLibrary(R); System.loadLibrary(R); return null; }})1140         AccessController.doPrivileged(new PrivilegedAction<Void>() {
1141             public Void run() {
1142                 // nio.dll has dependency on net.dll
1143                 System.loadLibrary("net");
1144                 System.loadLibrary("nio");
1145                 return null;
1146         }});
initIDs()1147         initIDs();
1148     }
1149 
1150 }
1151