1 /*
2  * Copyright (c) 2008, 2018, 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 #include <stdio.h>
27 #include <stdlib.h>
28 #include <ctype.h>
29 #include <direct.h>
30 #include <malloc.h>
31 #include <io.h>
32 #include <windows.h>
33 #include <aclapi.h>
34 #include <winioctl.h>
35 #include <Sddl.h>
36 
37 #include "jni.h"
38 #include "jni_util.h"
39 #include "jlong.h"
40 
41 #include "sun_nio_fs_WindowsNativeDispatcher.h"
42 
43 /**
44  * jfieldIDs
45  */
46 static jfieldID findFirst_handle;
47 static jfieldID findFirst_name;
48 static jfieldID findFirst_attributes;
49 
50 static jfieldID findStream_handle;
51 static jfieldID findStream_name;
52 
53 static jfieldID volumeInfo_fsName;
54 static jfieldID volumeInfo_volName;
55 static jfieldID volumeInfo_volSN;
56 static jfieldID volumeInfo_flags;
57 
58 static jfieldID diskSpace_bytesAvailable;
59 static jfieldID diskSpace_totalBytes;
60 static jfieldID diskSpace_totalFree;
61 
62 static jfieldID diskSpace_bytesPerSector;
63 
64 static jfieldID account_domain;
65 static jfieldID account_name;
66 static jfieldID account_use;
67 
68 static jfieldID aclInfo_aceCount;
69 
70 static jfieldID completionStatus_error;
71 static jfieldID completionStatus_bytesTransferred;
72 static jfieldID completionStatus_completionKey;
73 
throwWindowsException(JNIEnv * env,DWORD lastError)74 static void throwWindowsException(JNIEnv* env, DWORD lastError) {
75     jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
76         "(I)V", lastError);
77     if (x != NULL) {
78         (*env)->Throw(env, x);
79     }
80 }
81 
82 /**
83  * Initializes jfieldIDs and get address of Win32 calls that are located
84  * at runtime.
85  */
86 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv * env,jclass this)87 Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
88 {
89     jclass clazz;
90 
91     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstFile");
92     CHECK_NULL(clazz);
93     findFirst_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
94     CHECK_NULL(findFirst_handle);
95     findFirst_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
96     CHECK_NULL(findFirst_name);
97     findFirst_attributes = (*env)->GetFieldID(env, clazz, "attributes", "I");
98     CHECK_NULL(findFirst_attributes);
99 
100     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstStream");
101     CHECK_NULL(clazz);
102     findStream_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
103     CHECK_NULL(findStream_handle);
104     findStream_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
105     CHECK_NULL(findStream_name);
106 
107     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$VolumeInformation");
108     CHECK_NULL(clazz);
109     volumeInfo_fsName = (*env)->GetFieldID(env, clazz, "fileSystemName", "Ljava/lang/String;");
110     CHECK_NULL(volumeInfo_fsName);
111     volumeInfo_volName = (*env)->GetFieldID(env, clazz, "volumeName", "Ljava/lang/String;");
112     CHECK_NULL(volumeInfo_volName);
113     volumeInfo_volSN = (*env)->GetFieldID(env, clazz, "volumeSerialNumber", "I");
114     CHECK_NULL(volumeInfo_volSN);
115     volumeInfo_flags = (*env)->GetFieldID(env, clazz, "flags", "I");
116     CHECK_NULL(volumeInfo_flags);
117 
118     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$DiskFreeSpace");
119     CHECK_NULL(clazz);
120     diskSpace_bytesAvailable = (*env)->GetFieldID(env, clazz, "freeBytesAvailable", "J");
121     CHECK_NULL(diskSpace_bytesAvailable);
122     diskSpace_totalBytes = (*env)->GetFieldID(env, clazz, "totalNumberOfBytes", "J");
123     CHECK_NULL(diskSpace_totalBytes);
124     diskSpace_totalFree = (*env)->GetFieldID(env, clazz, "totalNumberOfFreeBytes", "J");
125     CHECK_NULL(diskSpace_totalFree);
126     diskSpace_bytesPerSector = (*env)->GetFieldID(env, clazz, "bytesPerSector", "J");
127     CHECK_NULL(diskSpace_bytesPerSector);
128 
129     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$Account");
130     CHECK_NULL(clazz);
131     account_domain = (*env)->GetFieldID(env, clazz, "domain", "Ljava/lang/String;");
132     CHECK_NULL(account_domain);
133     account_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
134     CHECK_NULL(account_name);
135     account_use = (*env)->GetFieldID(env, clazz, "use", "I");
136     CHECK_NULL(account_use);
137 
138     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$AclInformation");
139     CHECK_NULL(clazz);
140     aclInfo_aceCount = (*env)->GetFieldID(env, clazz, "aceCount", "I");
141     CHECK_NULL(aclInfo_aceCount);
142 
143     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$CompletionStatus");
144     CHECK_NULL(clazz);
145     completionStatus_error = (*env)->GetFieldID(env, clazz, "error", "I");
146     CHECK_NULL(completionStatus_error);
147     completionStatus_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
148     CHECK_NULL(completionStatus_bytesTransferred);
149     completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "J");
150     CHECK_NULL(completionStatus_completionKey);
151 }
152 
153 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateEvent(JNIEnv * env,jclass this,jboolean bManualReset,jboolean bInitialState)154 Java_sun_nio_fs_WindowsNativeDispatcher_CreateEvent(JNIEnv* env, jclass this,
155     jboolean bManualReset, jboolean bInitialState)
156 {
157     HANDLE hEvent = CreateEventW(NULL, bManualReset, bInitialState, NULL);
158     if (hEvent == NULL) {
159         throwWindowsException(env, GetLastError());
160     }
161     return ptr_to_jlong(hEvent);
162 }
163 
164 JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FormatMessage(JNIEnv * env,jclass this,jint errorCode)165 Java_sun_nio_fs_WindowsNativeDispatcher_FormatMessage(JNIEnv* env, jclass this, jint errorCode) {
166     WCHAR message[255];
167 
168     DWORD len = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
169                                NULL,
170                                (DWORD)errorCode,
171                                0,
172                                &message[0],
173                                255,
174                                NULL);
175 
176 
177     if (len == 0) {
178         return NULL;
179     } else {
180         return (*env)->NewString(env, (const jchar *)message, (jsize)wcslen(message));
181     }
182 }
183 
184 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_LocalFree(JNIEnv * env,jclass this,jlong address)185 Java_sun_nio_fs_WindowsNativeDispatcher_LocalFree(JNIEnv* env, jclass this, jlong address)
186 {
187     HLOCAL hMem = (HLOCAL)jlong_to_ptr(address);
188     LocalFree(hMem);
189 }
190 
191 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateFile0(JNIEnv * env,jclass this,jlong address,jint dwDesiredAccess,jint dwShareMode,jlong sdAddress,jint dwCreationDisposition,jint dwFlagsAndAttributes)192 Java_sun_nio_fs_WindowsNativeDispatcher_CreateFile0(JNIEnv* env, jclass this,
193     jlong address, jint dwDesiredAccess, jint dwShareMode, jlong sdAddress,
194     jint dwCreationDisposition, jint dwFlagsAndAttributes)
195 {
196     HANDLE handle;
197     LPCWSTR lpFileName = jlong_to_ptr(address);
198 
199     SECURITY_ATTRIBUTES securityAttributes;
200     LPSECURITY_ATTRIBUTES lpSecurityAttributes;
201     PSECURITY_DESCRIPTOR lpSecurityDescriptor = jlong_to_ptr(sdAddress);
202 
203 
204     if (lpSecurityDescriptor == NULL) {
205         lpSecurityAttributes = NULL;
206     } else {
207         securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
208         securityAttributes.lpSecurityDescriptor = lpSecurityDescriptor;
209         securityAttributes.bInheritHandle = FALSE;
210         lpSecurityAttributes = &securityAttributes;
211     }
212 
213     handle = CreateFileW(lpFileName,
214                         (DWORD)dwDesiredAccess,
215                         (DWORD)dwShareMode,
216                         lpSecurityAttributes,
217                         (DWORD)dwCreationDisposition,
218                         (DWORD)dwFlagsAndAttributes,
219                         NULL);
220     if (handle == INVALID_HANDLE_VALUE) {
221         throwWindowsException(env, GetLastError());
222     }
223     return ptr_to_jlong(handle);
224 }
225 
226 
227 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_DeviceIoControlSetSparse(JNIEnv * env,jclass this,jlong handle)228 Java_sun_nio_fs_WindowsNativeDispatcher_DeviceIoControlSetSparse(JNIEnv* env, jclass this,
229     jlong handle)
230 {
231     DWORD bytesReturned;
232     HANDLE h = (HANDLE)jlong_to_ptr(handle);
233     if (DeviceIoControl(h, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &bytesReturned, NULL) == 0) {
234         throwWindowsException(env, GetLastError());
235     }
236 }
237 
238 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_DeviceIoControlGetReparsePoint(JNIEnv * env,jclass this,jlong handle,jlong bufferAddress,jint bufferSize)239 Java_sun_nio_fs_WindowsNativeDispatcher_DeviceIoControlGetReparsePoint(JNIEnv* env, jclass this,
240     jlong handle, jlong bufferAddress, jint bufferSize)
241 {
242     DWORD bytesReturned;
243     HANDLE h = (HANDLE)jlong_to_ptr(handle);
244     LPVOID outBuffer = (LPVOID)jlong_to_ptr(bufferAddress);
245 
246     if (DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, outBuffer, (DWORD)bufferSize,
247                         &bytesReturned, NULL) == 0)
248     {
249         throwWindowsException(env, GetLastError());
250     }
251 }
252 
253 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_DeleteFile0(JNIEnv * env,jclass this,jlong address)254 Java_sun_nio_fs_WindowsNativeDispatcher_DeleteFile0(JNIEnv* env, jclass this, jlong address)
255 {
256     LPCWSTR lpFileName = jlong_to_ptr(address);
257     if (DeleteFileW(lpFileName) == 0) {
258         throwWindowsException(env, GetLastError());
259     }
260 }
261 
262 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateDirectory0(JNIEnv * env,jclass this,jlong address,jlong sdAddress)263 Java_sun_nio_fs_WindowsNativeDispatcher_CreateDirectory0(JNIEnv* env, jclass this,
264     jlong address, jlong sdAddress)
265 {
266     LPCWSTR lpFileName = jlong_to_ptr(address);
267 
268     SECURITY_ATTRIBUTES securityAttributes;
269     LPSECURITY_ATTRIBUTES lpSecurityAttributes;
270     PSECURITY_DESCRIPTOR lpSecurityDescriptor = jlong_to_ptr(sdAddress);
271 
272 
273     if (lpSecurityDescriptor == NULL) {
274         lpSecurityAttributes = NULL;
275     } else {
276         securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
277         securityAttributes.lpSecurityDescriptor = lpSecurityDescriptor;
278         securityAttributes.bInheritHandle = FALSE;
279         lpSecurityAttributes = &securityAttributes;
280     }
281 
282     if (CreateDirectoryW(lpFileName, lpSecurityAttributes) == 0) {
283         throwWindowsException(env, GetLastError());
284     }
285 }
286 
287 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_RemoveDirectory0(JNIEnv * env,jclass this,jlong address)288 Java_sun_nio_fs_WindowsNativeDispatcher_RemoveDirectory0(JNIEnv* env, jclass this, jlong address)
289 {
290     LPCWSTR lpFileName = jlong_to_ptr(address);
291     if (RemoveDirectoryW(lpFileName) == 0) {
292         throwWindowsException(env, GetLastError());
293     }
294 }
295 
296 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CloseHandle(JNIEnv * env,jclass this,jlong handle)297 Java_sun_nio_fs_WindowsNativeDispatcher_CloseHandle(JNIEnv* env, jclass this,
298     jlong handle)
299 {
300     HANDLE h = (HANDLE)jlong_to_ptr(handle);
301     CloseHandle(h);
302 }
303 
304 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstFile0(JNIEnv * env,jclass this,jlong address,jobject obj)305 Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstFile0(JNIEnv* env, jclass this,
306     jlong address, jobject obj)
307 {
308     WIN32_FIND_DATAW data;
309     LPCWSTR lpFileName = jlong_to_ptr(address);
310 
311     HANDLE handle = FindFirstFileW(lpFileName, &data);
312     if (handle != INVALID_HANDLE_VALUE) {
313         jstring name = (*env)->NewString(env, data.cFileName, (jsize)wcslen(data.cFileName));
314         if (name == NULL) {
315             FindClose(handle);
316             return;
317         }
318         (*env)->SetLongField(env, obj, findFirst_handle, ptr_to_jlong(handle));
319         (*env)->SetObjectField(env, obj, findFirst_name, name);
320         (*env)->SetIntField(env, obj, findFirst_attributes, data.dwFileAttributes);
321     } else {
322         throwWindowsException(env, GetLastError());
323     }
324 }
325 
326 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstFile1(JNIEnv * env,jclass this,jlong pathAddress,jlong dataAddress)327 Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstFile1(JNIEnv* env, jclass this,
328     jlong pathAddress, jlong dataAddress)
329 {
330     LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
331     WIN32_FIND_DATAW* data = (WIN32_FIND_DATAW*)jlong_to_ptr(dataAddress);
332 
333     HANDLE handle = FindFirstFileW(lpFileName, data);
334     if (handle == INVALID_HANDLE_VALUE) {
335         throwWindowsException(env, GetLastError());
336     }
337     return ptr_to_jlong(handle);
338 }
339 
340 JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindNextFile(JNIEnv * env,jclass this,jlong handle,jlong dataAddress)341 Java_sun_nio_fs_WindowsNativeDispatcher_FindNextFile(JNIEnv* env, jclass this,
342     jlong handle, jlong dataAddress)
343 {
344     HANDLE h = (HANDLE)jlong_to_ptr(handle);
345     WIN32_FIND_DATAW* data = (WIN32_FIND_DATAW*)jlong_to_ptr(dataAddress);
346 
347     if (FindNextFileW(h, data) != 0) {
348         return (*env)->NewString(env, data->cFileName, (jsize)wcslen(data->cFileName));
349     } else {
350     if (GetLastError() != ERROR_NO_MORE_FILES)
351         throwWindowsException(env, GetLastError());
352         return NULL;
353     }
354 }
355 
356 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstStream0(JNIEnv * env,jclass this,jlong address,jobject obj)357 Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstStream0(JNIEnv* env, jclass this,
358     jlong address, jobject obj)
359 {
360     WIN32_FIND_STREAM_DATA data;
361     LPCWSTR lpFileName = jlong_to_ptr(address);
362     HANDLE handle;
363 
364     handle = FindFirstStreamW(lpFileName, FindStreamInfoStandard, &data, 0);
365     if (handle != INVALID_HANDLE_VALUE) {
366         jstring name = (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
367         if (name == NULL) {
368             FindClose(handle);
369             return;
370         }
371         (*env)->SetLongField(env, obj, findStream_handle, ptr_to_jlong(handle));
372         (*env)->SetObjectField(env, obj, findStream_name, name);
373     } else {
374         if (GetLastError() == ERROR_HANDLE_EOF) {
375              (*env)->SetLongField(env, obj, findStream_handle, ptr_to_jlong(handle));
376         } else {
377             throwWindowsException(env, GetLastError());
378         }
379     }
380 
381 }
382 
383 JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindNextStream(JNIEnv * env,jclass this,jlong handle)384 Java_sun_nio_fs_WindowsNativeDispatcher_FindNextStream(JNIEnv* env, jclass this,
385     jlong handle)
386 {
387     WIN32_FIND_STREAM_DATA data;
388     HANDLE h = (HANDLE)jlong_to_ptr(handle);
389 
390     if (FindNextStreamW(h, &data) != 0) {
391         return (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
392     } else {
393         if (GetLastError() != ERROR_HANDLE_EOF)
394             throwWindowsException(env, GetLastError());
395         return NULL;
396     }
397 }
398 
399 
400 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindClose(JNIEnv * env,jclass this,jlong handle)401 Java_sun_nio_fs_WindowsNativeDispatcher_FindClose(JNIEnv* env, jclass this,
402     jlong handle)
403 {
404     HANDLE h = (HANDLE)jlong_to_ptr(handle);
405     if (FindClose(h) == 0) {
406         throwWindowsException(env, GetLastError());
407     }
408 }
409 
410 
411 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileInformationByHandle(JNIEnv * env,jclass this,jlong handle,jlong address)412 Java_sun_nio_fs_WindowsNativeDispatcher_GetFileInformationByHandle(JNIEnv* env, jclass this,
413     jlong handle, jlong address)
414 {
415     HANDLE h = (HANDLE)jlong_to_ptr(handle);
416     BY_HANDLE_FILE_INFORMATION* info =
417         (BY_HANDLE_FILE_INFORMATION*)jlong_to_ptr(address);
418     if (GetFileInformationByHandle(h, info) == 0) {
419         throwWindowsException(env, GetLastError());
420     }
421 }
422 
423 
424 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CopyFileEx0(JNIEnv * env,jclass this,jlong existingAddress,jlong newAddress,jint flags,jlong cancelAddress)425 Java_sun_nio_fs_WindowsNativeDispatcher_CopyFileEx0(JNIEnv* env, jclass this,
426     jlong existingAddress, jlong newAddress, jint flags, jlong cancelAddress)
427 {
428     LPCWSTR lpExistingFileName = jlong_to_ptr(existingAddress);
429     LPCWSTR lpNewFileName = jlong_to_ptr(newAddress);
430     LPBOOL cancel = (LPBOOL)jlong_to_ptr(cancelAddress);
431     if (CopyFileExW(lpExistingFileName, lpNewFileName, NULL, NULL, cancel,
432                     (DWORD)flags) == 0)
433     {
434         throwWindowsException(env, GetLastError());
435     }
436 }
437 
438 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_MoveFileEx0(JNIEnv * env,jclass this,jlong existingAddress,jlong newAddress,jint flags)439 Java_sun_nio_fs_WindowsNativeDispatcher_MoveFileEx0(JNIEnv* env, jclass this,
440     jlong existingAddress, jlong newAddress, jint flags)
441 {
442     LPCWSTR lpExistingFileName = jlong_to_ptr(existingAddress);
443     LPCWSTR lpNewFileName = jlong_to_ptr(newAddress);
444     if (MoveFileExW(lpExistingFileName, lpNewFileName, (DWORD)flags) == 0) {
445         throwWindowsException(env, GetLastError());
446     }
447 }
448 
449 JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetLogicalDrives(JNIEnv * env,jclass this)450 Java_sun_nio_fs_WindowsNativeDispatcher_GetLogicalDrives(JNIEnv* env, jclass this)
451 {
452     DWORD res = GetLogicalDrives();
453     if (res == 0) {
454         throwWindowsException(env, GetLastError());
455     }
456     return (jint)res;
457 }
458 
459 JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileAttributes0(JNIEnv * env,jclass this,jlong address)460 Java_sun_nio_fs_WindowsNativeDispatcher_GetFileAttributes0(JNIEnv* env, jclass this,
461     jlong address)
462 {
463     LPCWSTR lpFileName = jlong_to_ptr(address);
464     DWORD value = GetFileAttributesW(lpFileName);
465 
466     if (value == INVALID_FILE_ATTRIBUTES) {
467         throwWindowsException(env, GetLastError());
468     }
469     return (jint)value;
470 }
471 
472 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetFileAttributes0(JNIEnv * env,jclass this,jlong address,jint value)473 Java_sun_nio_fs_WindowsNativeDispatcher_SetFileAttributes0(JNIEnv* env, jclass this,
474     jlong address, jint value)
475 {
476     LPCWSTR lpFileName = jlong_to_ptr(address);
477     if (SetFileAttributesW(lpFileName, (DWORD)value) == 0) {
478         throwWindowsException(env, GetLastError());
479     }
480 }
481 
482 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileAttributesEx0(JNIEnv * env,jclass this,jlong pathAddress,jlong dataAddress)483 Java_sun_nio_fs_WindowsNativeDispatcher_GetFileAttributesEx0(JNIEnv* env, jclass this,
484     jlong pathAddress, jlong dataAddress)
485 {
486     LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
487     WIN32_FILE_ATTRIBUTE_DATA* data = (WIN32_FILE_ATTRIBUTE_DATA*)jlong_to_ptr(dataAddress);
488 
489     BOOL res = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, (LPVOID)data);
490     if (res == 0)
491         throwWindowsException(env, GetLastError());
492 }
493 
494 
495 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetFileTime(JNIEnv * env,jclass this,jlong handle,jlong createTime,jlong lastAccessTime,jlong lastWriteTime)496 Java_sun_nio_fs_WindowsNativeDispatcher_SetFileTime(JNIEnv* env, jclass this,
497     jlong handle, jlong createTime, jlong lastAccessTime, jlong lastWriteTime)
498 {
499     HANDLE h = (HANDLE)jlong_to_ptr(handle);
500 
501     if (SetFileTime(h,
502         (createTime == (jlong)-1) ? NULL : (CONST FILETIME *)&createTime,
503         (lastAccessTime == (jlong)-1) ? NULL : (CONST FILETIME *)&lastAccessTime,
504         (lastWriteTime == (jlong)-1) ? NULL : (CONST FILETIME *)&lastWriteTime) == 0)
505     {
506         throwWindowsException(env, GetLastError());
507     }
508 }
509 
510 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetEndOfFile(JNIEnv * env,jclass this,jlong handle)511 Java_sun_nio_fs_WindowsNativeDispatcher_SetEndOfFile(JNIEnv* env, jclass this,
512     jlong handle)
513 {
514     HANDLE h = (HANDLE)jlong_to_ptr(handle);
515 
516     if (SetEndOfFile(h) == 0)
517         throwWindowsException(env, GetLastError());
518 }
519 
520 
521 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetVolumeInformation0(JNIEnv * env,jclass this,jlong address,jobject obj)522 Java_sun_nio_fs_WindowsNativeDispatcher_GetVolumeInformation0(JNIEnv* env, jclass this,
523     jlong address, jobject obj)
524 {
525     WCHAR volumeName[MAX_PATH+1];
526     DWORD volumeSerialNumber;
527     DWORD maxComponentLength;
528     DWORD flags;
529     WCHAR fileSystemName[MAX_PATH+1];
530     LPCWSTR lpFileName = jlong_to_ptr(address);
531     jstring str;
532 
533     BOOL res = GetVolumeInformationW(lpFileName,
534                                      &volumeName[0],
535                                      MAX_PATH+1,
536                                      &volumeSerialNumber,
537                                      &maxComponentLength,
538                                      &flags,
539                                      &fileSystemName[0],
540                                      MAX_PATH+1);
541     if (res == 0) {
542         throwWindowsException(env, GetLastError());
543         return;
544     }
545 
546     str = (*env)->NewString(env, (const jchar *)fileSystemName, (jsize)wcslen(fileSystemName));
547     if (str == NULL) return;
548     (*env)->SetObjectField(env, obj, volumeInfo_fsName, str);
549 
550     str = (*env)->NewString(env, (const jchar *)volumeName, (jsize)wcslen(volumeName));
551     if (str == NULL) return;
552     (*env)->SetObjectField(env, obj, volumeInfo_volName, str);
553 
554     (*env)->SetIntField(env, obj, volumeInfo_volSN, (jint)volumeSerialNumber);
555     (*env)->SetIntField(env, obj, volumeInfo_flags, (jint)flags);
556 }
557 
558 
559 JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetDriveType0(JNIEnv * env,jclass this,jlong address)560 Java_sun_nio_fs_WindowsNativeDispatcher_GetDriveType0(JNIEnv* env, jclass this, jlong address) {
561     LPCWSTR lpRootPathName = jlong_to_ptr(address);
562     return (jint)GetDriveTypeW(lpRootPathName);
563 }
564 
565 
566 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetDiskFreeSpaceEx0(JNIEnv * env,jclass this,jlong address,jobject obj)567 Java_sun_nio_fs_WindowsNativeDispatcher_GetDiskFreeSpaceEx0(JNIEnv* env, jclass this,
568     jlong address, jobject obj)
569 {
570     ULARGE_INTEGER freeBytesAvailable;
571     ULARGE_INTEGER totalNumberOfBytes;
572     ULARGE_INTEGER totalNumberOfFreeBytes;
573     LPCWSTR lpDirName = jlong_to_ptr(address);
574 
575 
576     BOOL res = GetDiskFreeSpaceExW(lpDirName,
577                                    &freeBytesAvailable,
578                                    &totalNumberOfBytes,
579                                    &totalNumberOfFreeBytes);
580     if (res == 0) {
581         throwWindowsException(env, GetLastError());
582         return;
583     }
584 
585     (*env)->SetLongField(env, obj, diskSpace_bytesAvailable,
586         long_to_jlong(freeBytesAvailable.QuadPart));
587     (*env)->SetLongField(env, obj, diskSpace_totalBytes,
588         long_to_jlong(totalNumberOfBytes.QuadPart));
589     (*env)->SetLongField(env, obj, diskSpace_totalFree,
590         long_to_jlong(totalNumberOfFreeBytes.QuadPart));
591 }
592 
593 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetDiskFreeSpace0(JNIEnv * env,jclass this,jlong address,jobject obj)594 Java_sun_nio_fs_WindowsNativeDispatcher_GetDiskFreeSpace0(JNIEnv* env, jclass this,
595     jlong address, jobject obj)
596 {
597     DWORD sectorsPerCluster;
598     DWORD bytesPerSector;
599     DWORD numberOfFreeClusters;
600     DWORD totalNumberOfClusters;
601     LPCWSTR lpRootPathName = jlong_to_ptr(address);
602 
603 
604     BOOL res = GetDiskFreeSpaceW(lpRootPathName,
605                                  &sectorsPerCluster,
606                                  &bytesPerSector,
607                                  &numberOfFreeClusters,
608                                  &totalNumberOfClusters);
609     if (res == 0) {
610         throwWindowsException(env, GetLastError());
611         return;
612     }
613 
614     (*env)->SetLongField(env, obj, diskSpace_bytesPerSector,
615         long_to_jlong(bytesPerSector));
616 }
617 
618 JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetVolumePathName0(JNIEnv * env,jclass this,jlong address)619 Java_sun_nio_fs_WindowsNativeDispatcher_GetVolumePathName0(JNIEnv* env, jclass this,
620     jlong address)
621 {
622     WCHAR volumeName[MAX_PATH+1];
623     LPCWSTR lpFileName = jlong_to_ptr(address);
624 
625 
626     BOOL res = GetVolumePathNameW(lpFileName,
627                                   &volumeName[0],
628                                   MAX_PATH+1);
629     if (res == 0) {
630         throwWindowsException(env, GetLastError());
631         return NULL;
632     } else {
633         return (*env)->NewString(env, (const jchar *)volumeName, (jsize)wcslen(volumeName));
634     }
635 }
636 
637 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_InitializeSecurityDescriptor(JNIEnv * env,jclass this,jlong address)638 Java_sun_nio_fs_WindowsNativeDispatcher_InitializeSecurityDescriptor(JNIEnv* env, jclass this,
639     jlong address)
640 {
641     PSECURITY_DESCRIPTOR pSecurityDescriptor =
642         (PSECURITY_DESCRIPTOR)jlong_to_ptr(address);
643 
644     if (InitializeSecurityDescriptor(pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) == 0) {
645         throwWindowsException(env, GetLastError());
646     }
647 }
648 
649 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_InitializeAcl(JNIEnv * env,jclass this,jlong address,jint size)650 Java_sun_nio_fs_WindowsNativeDispatcher_InitializeAcl(JNIEnv* env, jclass this,
651     jlong address, jint size)
652 {
653     PACL pAcl = (PACL)jlong_to_ptr(address);
654 
655     if (InitializeAcl(pAcl, (DWORD)size, ACL_REVISION) == 0) {
656         throwWindowsException(env, GetLastError());
657     }
658 }
659 
660 
661 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetFileSecurity0(JNIEnv * env,jclass this,jlong pathAddress,jint requestedInformation,jlong descAddress)662 Java_sun_nio_fs_WindowsNativeDispatcher_SetFileSecurity0(JNIEnv* env, jclass this,
663     jlong pathAddress, jint requestedInformation, jlong descAddress)
664 {
665     LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
666     PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(descAddress);
667     DWORD lengthNeeded = 0;
668 
669     BOOL res = SetFileSecurityW(lpFileName,
670                                 (SECURITY_INFORMATION)requestedInformation,
671                                 pSecurityDescriptor);
672 
673     if (res == 0) {
674         throwWindowsException(env, GetLastError());
675     }
676 }
677 
678 JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileSecurity0(JNIEnv * env,jclass this,jlong pathAddress,jint requestedInformation,jlong descAddress,jint nLength)679 Java_sun_nio_fs_WindowsNativeDispatcher_GetFileSecurity0(JNIEnv* env, jclass this,
680     jlong pathAddress, jint requestedInformation, jlong descAddress, jint nLength)
681 {
682     LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
683     PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(descAddress);
684     DWORD lengthNeeded = 0;
685 
686     BOOL res = GetFileSecurityW(lpFileName,
687                                 (SECURITY_INFORMATION)requestedInformation,
688                                 pSecurityDescriptor,
689                                 (DWORD)nLength,
690                                 &lengthNeeded);
691 
692     if (res == 0) {
693         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
694             return (jint)lengthNeeded;
695         } else {
696             throwWindowsException(env, GetLastError());
697             return 0;
698         }
699     } else {
700         return (jint)nLength;
701     }
702 }
703 
704 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetSecurityDescriptorOwner(JNIEnv * env,jclass this,jlong address)705 Java_sun_nio_fs_WindowsNativeDispatcher_GetSecurityDescriptorOwner(JNIEnv* env,
706     jclass this, jlong address)
707 {
708     PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(address);
709     PSID pOwner;
710     BOOL bOwnerDefaulted;
711 
712 
713     if (GetSecurityDescriptorOwner(pSecurityDescriptor, &pOwner, &bOwnerDefaulted) == 0) {
714         throwWindowsException(env, GetLastError());
715     }
716     return ptr_to_jlong(pOwner);
717 }
718 
719 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetSecurityDescriptorOwner(JNIEnv * env,jclass this,jlong descAddress,jlong ownerAddress)720 Java_sun_nio_fs_WindowsNativeDispatcher_SetSecurityDescriptorOwner(JNIEnv* env,
721     jclass this, jlong descAddress, jlong ownerAddress)
722 {
723     PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(descAddress);
724     PSID pOwner = jlong_to_ptr(ownerAddress);
725 
726     if (SetSecurityDescriptorOwner(pSecurityDescriptor, pOwner, FALSE) == 0) {
727         throwWindowsException(env, GetLastError());
728     }
729 }
730 
731 
732 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetSecurityDescriptorDacl(JNIEnv * env,jclass this,jlong address)733 Java_sun_nio_fs_WindowsNativeDispatcher_GetSecurityDescriptorDacl(JNIEnv* env,
734     jclass this, jlong address)
735 {
736     PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(address);
737     BOOL bDaclPresent;
738     PACL pDacl;
739     BOOL bDaclDefaulted;
740 
741     if (GetSecurityDescriptorDacl(pSecurityDescriptor, &bDaclPresent, &pDacl, &bDaclDefaulted) == 0) {
742         throwWindowsException(env, GetLastError());
743         return (jlong)0;
744     } else {
745         return (bDaclPresent) ? ptr_to_jlong(pDacl) : (jlong)0;
746     }
747 }
748 
749 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetSecurityDescriptorDacl(JNIEnv * env,jclass this,jlong descAddress,jlong aclAddress)750 Java_sun_nio_fs_WindowsNativeDispatcher_SetSecurityDescriptorDacl(JNIEnv* env,
751     jclass this, jlong descAddress, jlong aclAddress)
752 {
753     PSECURITY_DESCRIPTOR pSecurityDescriptor = (PSECURITY_DESCRIPTOR)jlong_to_ptr(descAddress);
754     PACL pAcl = (PACL)jlong_to_ptr(aclAddress);
755 
756     if (SetSecurityDescriptorDacl(pSecurityDescriptor, TRUE, pAcl, FALSE) == 0) {
757         throwWindowsException(env, GetLastError());
758     }
759 }
760 
761 
762 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetAclInformation0(JNIEnv * env,jclass this,jlong address,jobject obj)763 Java_sun_nio_fs_WindowsNativeDispatcher_GetAclInformation0(JNIEnv* env,
764     jclass this, jlong address, jobject obj)
765 {
766     PACL pAcl = (PACL)jlong_to_ptr(address);
767     ACL_SIZE_INFORMATION acl_size_info;
768 
769     if (GetAclInformation(pAcl, (void *) &acl_size_info, sizeof(acl_size_info), AclSizeInformation) == 0) {
770         throwWindowsException(env, GetLastError());
771     } else {
772         (*env)->SetIntField(env, obj, aclInfo_aceCount, (jint)acl_size_info.AceCount);
773     }
774 }
775 
776 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetAce(JNIEnv * env,jclass this,jlong address,jint aceIndex)777 Java_sun_nio_fs_WindowsNativeDispatcher_GetAce(JNIEnv* env, jclass this, jlong address,
778     jint aceIndex)
779 {
780     PACL pAcl = (PACL)jlong_to_ptr(address);
781     LPVOID pAce;
782 
783     if (GetAce(pAcl, (DWORD)aceIndex, &pAce) == 0) {
784         throwWindowsException(env, GetLastError());
785         return (jlong)0;
786     } else {
787         return ptr_to_jlong(pAce);
788     }
789 }
790 
791 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_AddAccessAllowedAceEx(JNIEnv * env,jclass this,jlong aclAddress,jint flags,jint mask,jlong sidAddress)792 Java_sun_nio_fs_WindowsNativeDispatcher_AddAccessAllowedAceEx(JNIEnv* env,
793     jclass this, jlong aclAddress, jint flags, jint mask, jlong sidAddress)
794 {
795     PACL pAcl = (PACL)jlong_to_ptr(aclAddress);
796     PSID pSid = (PSID)jlong_to_ptr(sidAddress);
797 
798     if (AddAccessAllowedAceEx(pAcl, ACL_REVISION, (DWORD)flags, (DWORD)mask, pSid) == 0) {
799         throwWindowsException(env, GetLastError());
800     }
801 }
802 
803 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_AddAccessDeniedAceEx(JNIEnv * env,jclass this,jlong aclAddress,jint flags,jint mask,jlong sidAddress)804 Java_sun_nio_fs_WindowsNativeDispatcher_AddAccessDeniedAceEx(JNIEnv* env,
805     jclass this, jlong aclAddress, jint flags, jint mask, jlong sidAddress)
806 {
807     PACL pAcl = (PACL)jlong_to_ptr(aclAddress);
808     PSID pSid = (PSID)jlong_to_ptr(sidAddress);
809 
810     if (AddAccessDeniedAceEx(pAcl, ACL_REVISION, (DWORD)flags, (DWORD)mask, pSid) == 0) {
811         throwWindowsException(env, GetLastError());
812     }
813 }
814 
815 
816 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_LookupAccountSid0(JNIEnv * env,jclass this,jlong address,jobject obj)817 Java_sun_nio_fs_WindowsNativeDispatcher_LookupAccountSid0(JNIEnv* env,
818     jclass this, jlong address, jobject obj)
819 {
820     WCHAR domain[255];
821     WCHAR name[255];
822     DWORD domainLen = sizeof(domain);
823     DWORD nameLen = sizeof(name);
824     SID_NAME_USE use;
825     PSID sid = jlong_to_ptr(address);
826     jstring s;
827 
828     if (LookupAccountSidW(NULL, sid, &name[0], &nameLen, &domain[0], &domainLen, &use) == 0) {
829         throwWindowsException(env, GetLastError());
830         return;
831     }
832 
833     s = (*env)->NewString(env, (const jchar *)domain, (jsize)wcslen(domain));
834     if (s == NULL)
835         return;
836     (*env)->SetObjectField(env, obj, account_domain, s);
837 
838     s = (*env)->NewString(env, (const jchar *)name, (jsize)wcslen(name));
839     if (s == NULL)
840         return;
841     (*env)->SetObjectField(env, obj, account_name, s);
842     (*env)->SetIntField(env, obj, account_use, (jint)use);
843 }
844 
845 JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_LookupAccountName0(JNIEnv * env,jclass this,jlong nameAddress,jlong sidAddress,jint cbSid)846 Java_sun_nio_fs_WindowsNativeDispatcher_LookupAccountName0(JNIEnv* env,
847     jclass this, jlong nameAddress, jlong sidAddress, jint cbSid)
848 {
849 
850     LPCWSTR accountName = jlong_to_ptr(nameAddress);
851     PSID sid = jlong_to_ptr(sidAddress);
852     WCHAR domain[255];
853     DWORD domainLen = sizeof(domain);
854     SID_NAME_USE use;
855 
856     if (LookupAccountNameW(NULL, accountName, sid, (LPDWORD)&cbSid,
857                            &domain[0], &domainLen, &use) == 0)
858     {
859         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
860             throwWindowsException(env, GetLastError());
861         }
862     }
863 
864     return cbSid;
865 }
866 
867 JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetLengthSid(JNIEnv * env,jclass this,jlong address)868 Java_sun_nio_fs_WindowsNativeDispatcher_GetLengthSid(JNIEnv* env,
869     jclass this, jlong address)
870 {
871     PSID sid = jlong_to_ptr(address);
872     return (jint)GetLengthSid(sid);
873 }
874 
875 
876 JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_ConvertSidToStringSid(JNIEnv * env,jclass this,jlong address)877 Java_sun_nio_fs_WindowsNativeDispatcher_ConvertSidToStringSid(JNIEnv* env,
878     jclass this, jlong address)
879 {
880     PSID sid = jlong_to_ptr(address);
881     LPWSTR string;
882     if (ConvertSidToStringSidW(sid, &string) == 0) {
883         throwWindowsException(env, GetLastError());
884         return NULL;
885     } else {
886         jstring s = (*env)->NewString(env, (const jchar *)string,
887             (jsize)wcslen(string));
888         LocalFree(string);
889         return s;
890     }
891 }
892 
893 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_ConvertStringSidToSid0(JNIEnv * env,jclass this,jlong address)894 Java_sun_nio_fs_WindowsNativeDispatcher_ConvertStringSidToSid0(JNIEnv* env,
895     jclass this, jlong address)
896 {
897     LPWSTR lpStringSid = jlong_to_ptr(address);
898     PSID pSid;
899     if (ConvertStringSidToSidW(lpStringSid, &pSid) == 0)
900         throwWindowsException(env, GetLastError());
901     return ptr_to_jlong(pSid);
902 }
903 
904 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetCurrentProcess(JNIEnv * env,jclass this)905 Java_sun_nio_fs_WindowsNativeDispatcher_GetCurrentProcess(JNIEnv* env, jclass this) {
906     HANDLE hProcess = GetCurrentProcess();
907     return ptr_to_jlong(hProcess);
908 }
909 
910 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetCurrentThread(JNIEnv * env,jclass this)911 Java_sun_nio_fs_WindowsNativeDispatcher_GetCurrentThread(JNIEnv* env, jclass this) {
912     HANDLE hThread = GetCurrentThread();
913     return ptr_to_jlong(hThread);
914 }
915 
916 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_OpenProcessToken(JNIEnv * env,jclass this,jlong process,jint desiredAccess)917 Java_sun_nio_fs_WindowsNativeDispatcher_OpenProcessToken(JNIEnv* env,
918     jclass this, jlong process, jint desiredAccess)
919 {
920     HANDLE hProcess = (HANDLE)jlong_to_ptr(process);
921     HANDLE hToken;
922 
923     if (OpenProcessToken(hProcess, (DWORD)desiredAccess, &hToken) == 0)
924         throwWindowsException(env, GetLastError());
925     return ptr_to_jlong(hToken);
926 }
927 
928 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_OpenThreadToken(JNIEnv * env,jclass this,jlong thread,jint desiredAccess,jboolean openAsSelf)929 Java_sun_nio_fs_WindowsNativeDispatcher_OpenThreadToken(JNIEnv* env,
930     jclass this, jlong thread, jint desiredAccess, jboolean openAsSelf)
931 {
932     HANDLE hThread = (HANDLE)jlong_to_ptr(thread);
933     HANDLE hToken;
934     BOOL bOpenAsSelf = (openAsSelf == JNI_TRUE) ? TRUE : FALSE;
935 
936     if (OpenThreadToken(hThread, (DWORD)desiredAccess, bOpenAsSelf, &hToken) == 0) {
937         if (GetLastError() == ERROR_NO_TOKEN)
938             return (jlong)0;
939         throwWindowsException(env, GetLastError());
940     }
941     return ptr_to_jlong(hToken);
942 }
943 
944 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_DuplicateTokenEx(JNIEnv * env,jclass this,jlong token,jint desiredAccess)945 Java_sun_nio_fs_WindowsNativeDispatcher_DuplicateTokenEx(JNIEnv* env,
946     jclass this, jlong token, jint desiredAccess)
947 {
948     HANDLE hToken = (HANDLE)jlong_to_ptr(token);
949     HANDLE resultToken;
950     BOOL res;
951 
952     res = DuplicateTokenEx(hToken,
953                            (DWORD)desiredAccess,
954                            NULL,
955                            SecurityImpersonation,
956                            TokenImpersonation,
957                            &resultToken);
958     if (res == 0)
959         throwWindowsException(env, GetLastError());
960     return ptr_to_jlong(resultToken);
961 }
962 
963 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetThreadToken(JNIEnv * env,jclass this,jlong thread,jlong token)964 Java_sun_nio_fs_WindowsNativeDispatcher_SetThreadToken(JNIEnv* env,
965     jclass this, jlong thread, jlong token)
966 {
967     HANDLE hThread = (HANDLE)jlong_to_ptr(thread);
968     HANDLE hToken = (HANDLE)jlong_to_ptr(token);
969 
970     if (SetThreadToken(hThread, hToken) == 0)
971         throwWindowsException(env, GetLastError());
972 }
973 
974 JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetTokenInformation(JNIEnv * env,jclass this,jlong token,jint tokenInfoClass,jlong tokenInfo,jint tokenInfoLength)975 Java_sun_nio_fs_WindowsNativeDispatcher_GetTokenInformation(JNIEnv* env,
976     jclass this, jlong token, jint tokenInfoClass, jlong tokenInfo, jint tokenInfoLength)
977 {
978     BOOL res;
979     DWORD lengthNeeded;
980     HANDLE hToken = (HANDLE)jlong_to_ptr(token);
981     LPVOID result = (LPVOID)jlong_to_ptr(tokenInfo);
982 
983     res = GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)tokenInfoClass, (LPVOID)result,
984                               tokenInfoLength, &lengthNeeded);
985     if (res == 0) {
986         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
987             return (jint)lengthNeeded;
988         } else {
989             throwWindowsException(env, GetLastError());
990             return 0;
991         }
992     } else {
993         return tokenInfoLength;
994     }
995 }
996 
997 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_AdjustTokenPrivileges(JNIEnv * env,jclass this,jlong token,jlong luid,jint attributes)998 Java_sun_nio_fs_WindowsNativeDispatcher_AdjustTokenPrivileges(JNIEnv* env,
999     jclass this, jlong token, jlong luid, jint attributes)
1000 {
1001     TOKEN_PRIVILEGES privs[1];
1002     HANDLE hToken = (HANDLE)jlong_to_ptr(token);
1003     PLUID pLuid = (PLUID)jlong_to_ptr(luid);
1004 
1005     privs[0].PrivilegeCount = 1;
1006     privs[0].Privileges[0].Luid = *pLuid;
1007     privs[0].Privileges[0].Attributes = (DWORD)attributes;
1008 
1009     if (AdjustTokenPrivileges(hToken, FALSE, &privs[0], 1, NULL, NULL) == 0)
1010         throwWindowsException(env, GetLastError());
1011 }
1012 
1013 JNIEXPORT jboolean JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_AccessCheck(JNIEnv * env,jclass this,jlong token,jlong securityInfo,jint accessMask,jint genericRead,jint genericWrite,jint genericExecute,jint genericAll)1014 Java_sun_nio_fs_WindowsNativeDispatcher_AccessCheck(JNIEnv* env,
1015     jclass this, jlong token, jlong securityInfo, jint accessMask,
1016     jint genericRead, jint genericWrite, jint genericExecute, jint genericAll)
1017 {
1018     HANDLE hImpersonatedToken = (HANDLE)jlong_to_ptr(token);
1019     PSECURITY_DESCRIPTOR security = (PSECURITY_DESCRIPTOR)jlong_to_ptr(securityInfo);
1020     DWORD checkAccessRights = (DWORD)accessMask;
1021     GENERIC_MAPPING mapping = {
1022         genericRead,
1023         genericWrite,
1024         genericExecute,
1025         genericAll};
1026     PRIVILEGE_SET privileges = {0};
1027     DWORD privilegesLength = sizeof(privileges);
1028     DWORD grantedAccess = 0;
1029     BOOL result = FALSE;
1030 
1031     /* checkAccessRights is in-out parameter */
1032     MapGenericMask(&checkAccessRights, &mapping);
1033     if (AccessCheck(security, hImpersonatedToken, checkAccessRights,
1034             &mapping, &privileges, &privilegesLength, &grantedAccess, &result) == 0)
1035         throwWindowsException(env, GetLastError());
1036 
1037     return (result == FALSE) ? JNI_FALSE : JNI_TRUE;
1038 }
1039 
1040 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_LookupPrivilegeValue0(JNIEnv * env,jclass this,jlong name)1041 Java_sun_nio_fs_WindowsNativeDispatcher_LookupPrivilegeValue0(JNIEnv* env,
1042     jclass this, jlong name)
1043 {
1044     LPCWSTR lpName = (LPCWSTR)jlong_to_ptr(name);
1045     PLUID pLuid = LocalAlloc(0, sizeof(LUID));
1046 
1047     if (pLuid == NULL) {
1048         JNU_ThrowInternalError(env, "Unable to allocate LUID structure");
1049     } else {
1050         if (LookupPrivilegeValueW(NULL, lpName, pLuid) == 0) {
1051             LocalFree(pLuid);
1052             throwWindowsException(env, GetLastError());
1053             return (jlong)0;
1054         }
1055     }
1056     return ptr_to_jlong(pLuid);
1057 }
1058 
1059 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateSymbolicLink0(JNIEnv * env,jclass this,jlong linkAddress,jlong targetAddress,jint flags)1060 Java_sun_nio_fs_WindowsNativeDispatcher_CreateSymbolicLink0(JNIEnv* env,
1061     jclass this, jlong linkAddress, jlong targetAddress, jint flags)
1062 {
1063     LPCWSTR link = jlong_to_ptr(linkAddress);
1064     LPCWSTR target = jlong_to_ptr(targetAddress);
1065 
1066     /* On Windows 64-bit this appears to succeed even when there is insufficient privileges */
1067     if (CreateSymbolicLinkW(link, target, (DWORD)flags) == 0)
1068         throwWindowsException(env, GetLastError());
1069 }
1070 
1071 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateHardLink0(JNIEnv * env,jclass this,jlong newFileAddress,jlong existingFileAddress)1072 Java_sun_nio_fs_WindowsNativeDispatcher_CreateHardLink0(JNIEnv* env,
1073     jclass this, jlong newFileAddress, jlong existingFileAddress)
1074 {
1075     LPCWSTR newFile = jlong_to_ptr(newFileAddress);
1076     LPCWSTR existingFile = jlong_to_ptr(existingFileAddress);
1077 
1078     if (CreateHardLinkW(newFile, existingFile, NULL) == 0)
1079         throwWindowsException(env, GetLastError());
1080 }
1081 
1082 JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFullPathName0(JNIEnv * env,jclass clz,jlong pathAddress)1083 Java_sun_nio_fs_WindowsNativeDispatcher_GetFullPathName0(JNIEnv *env,
1084                                                          jclass clz,
1085                                                          jlong pathAddress)
1086 {
1087     jstring rv = NULL;
1088     WCHAR *lpBuf = NULL;
1089     WCHAR buf[MAX_PATH];
1090     DWORD len;
1091     LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
1092 
1093     len = GetFullPathNameW(lpFileName, MAX_PATH, buf, NULL);
1094     if (len > 0) {
1095         if (len < MAX_PATH) {
1096             rv = (*env)->NewString(env, buf, len);
1097         } else {
1098             len += 1;  /* return length does not include terminator */
1099             lpBuf = (WCHAR*)malloc(len * sizeof(WCHAR));
1100             if (lpBuf != NULL) {
1101                 len = GetFullPathNameW(lpFileName, len, lpBuf, NULL);
1102                 if (len > 0) {
1103                     rv = (*env)->NewString(env, lpBuf, len);
1104                 } else {
1105                     JNU_ThrowInternalError(env, "GetFullPathNameW failed");
1106                 }
1107                 free(lpBuf);
1108             } else {
1109                 JNU_ThrowOutOfMemoryError(env, "native memory allocation failure");
1110             }
1111         }
1112     } else {
1113         throwWindowsException(env, GetLastError());
1114     }
1115 
1116     return rv;
1117 }
1118 
1119 JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFinalPathNameByHandle(JNIEnv * env,jclass this,jlong handle)1120 Java_sun_nio_fs_WindowsNativeDispatcher_GetFinalPathNameByHandle(JNIEnv* env,
1121     jclass this, jlong handle)
1122 {
1123     jstring rv = NULL;
1124     WCHAR *lpBuf = NULL;
1125     WCHAR path[MAX_PATH];
1126     HANDLE h = (HANDLE)jlong_to_ptr(handle);
1127     DWORD len;
1128 
1129     len = GetFinalPathNameByHandleW(h, path, MAX_PATH, 0);
1130     if (len > 0) {
1131         if (len < MAX_PATH) {
1132             rv = (*env)->NewString(env, (const jchar *)path, (jsize)len);
1133         } else {
1134             len += 1;  /* return length does not include terminator */
1135             lpBuf = (WCHAR*)malloc(len * sizeof(WCHAR));
1136             if (lpBuf != NULL) {
1137                 len = GetFinalPathNameByHandleW(h, lpBuf, len, 0);
1138                 if (len > 0)  {
1139                     rv = (*env)->NewString(env, (const jchar *)lpBuf, (jsize)len);
1140                 } else {
1141                     JNU_ThrowInternalError(env, "GetFinalPathNameByHandleW failed");
1142                 }
1143                 free(lpBuf);
1144             } else {
1145                 JNU_ThrowOutOfMemoryError(env, "native memory allocation failure");
1146             }
1147         }
1148     } else {
1149         throwWindowsException(env, GetLastError());
1150     }
1151     return rv;
1152 }
1153 
1154 JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateIoCompletionPort(JNIEnv * env,jclass this,jlong fileHandle,jlong existingPort,jlong completionKey)1155 Java_sun_nio_fs_WindowsNativeDispatcher_CreateIoCompletionPort(JNIEnv* env, jclass this,
1156     jlong fileHandle, jlong existingPort, jlong completionKey)
1157 {
1158     HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(fileHandle),
1159                                          (HANDLE)jlong_to_ptr(existingPort),
1160                                          (ULONG_PTR)completionKey,
1161                                          0);
1162     if (port == NULL) {
1163         throwWindowsException(env, GetLastError());
1164     }
1165     return ptr_to_jlong(port);
1166 }
1167 
1168 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetQueuedCompletionStatus0(JNIEnv * env,jclass this,jlong completionPort,jobject obj)1169 Java_sun_nio_fs_WindowsNativeDispatcher_GetQueuedCompletionStatus0(JNIEnv* env, jclass this,
1170     jlong completionPort, jobject obj)
1171 {
1172     DWORD bytesTransferred;
1173     ULONG_PTR completionKey;
1174     OVERLAPPED *lpOverlapped;
1175     BOOL res;
1176 
1177     res = GetQueuedCompletionStatus((HANDLE)jlong_to_ptr(completionPort),
1178                                   &bytesTransferred,
1179                                   &completionKey,
1180                                   &lpOverlapped,
1181                                   INFINITE);
1182     if (res == 0 && lpOverlapped == NULL) {
1183         throwWindowsException(env, GetLastError());
1184     } else {
1185         DWORD ioResult = (res == 0) ? GetLastError() : 0;
1186         (*env)->SetIntField(env, obj, completionStatus_error, ioResult);
1187         (*env)->SetIntField(env, obj, completionStatus_bytesTransferred,
1188             (jint)bytesTransferred);
1189         (*env)->SetLongField(env, obj, completionStatus_completionKey,
1190             (jlong)completionKey);
1191     }
1192 }
1193 
1194 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_PostQueuedCompletionStatus(JNIEnv * env,jclass this,jlong completionPort,jlong completionKey)1195 Java_sun_nio_fs_WindowsNativeDispatcher_PostQueuedCompletionStatus(JNIEnv* env, jclass this,
1196     jlong completionPort, jlong completionKey)
1197 {
1198     BOOL res;
1199 
1200     res = PostQueuedCompletionStatus((HANDLE)jlong_to_ptr(completionPort),
1201                                      (DWORD)0,  /* dwNumberOfBytesTransferred */
1202                                      (ULONG_PTR)completionKey,
1203                                      NULL);  /* lpOverlapped */
1204     if (res == 0) {
1205         throwWindowsException(env, GetLastError());
1206     }
1207 }
1208 
1209 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CancelIo(JNIEnv * env,jclass this,jlong hFile)1210 Java_sun_nio_fs_WindowsNativeDispatcher_CancelIo(JNIEnv* env, jclass this, jlong hFile) {
1211     if (CancelIo((HANDLE)jlong_to_ptr(hFile)) == 0) {
1212         throwWindowsException(env, GetLastError());
1213     }
1214 }
1215 
1216 JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetOverlappedResult(JNIEnv * env,jclass this,jlong hFile,jlong lpOverlapped)1217 Java_sun_nio_fs_WindowsNativeDispatcher_GetOverlappedResult(JNIEnv *env, jclass this,
1218     jlong hFile, jlong lpOverlapped)
1219 {
1220     BOOL res;
1221     DWORD bytesTransferred = -1;
1222 
1223     res = GetOverlappedResult((HANDLE)jlong_to_ptr(hFile),
1224                               (LPOVERLAPPED)jlong_to_ptr(lpOverlapped),
1225                               &bytesTransferred,
1226                               TRUE);
1227     if (res == 0) {
1228         throwWindowsException(env, GetLastError());
1229     }
1230 
1231     return (jint)bytesTransferred;
1232 }
1233 
1234 JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_ReadDirectoryChangesW(JNIEnv * env,jclass this,jlong hDirectory,jlong bufferAddress,jint bufferLength,jboolean watchSubTree,jint filter,jlong bytesReturnedAddress,jlong pOverlapped)1235 Java_sun_nio_fs_WindowsNativeDispatcher_ReadDirectoryChangesW(JNIEnv* env, jclass this,
1236     jlong hDirectory, jlong bufferAddress, jint bufferLength, jboolean watchSubTree, jint filter,
1237     jlong bytesReturnedAddress, jlong pOverlapped)
1238 {
1239     BOOL res;
1240     BOOL subtree = (watchSubTree == JNI_TRUE) ? TRUE : FALSE;
1241     LPOVERLAPPED ov = (LPOVERLAPPED)jlong_to_ptr(pOverlapped);
1242 
1243     res = ReadDirectoryChangesW((HANDLE)jlong_to_ptr(hDirectory),
1244                                 (LPVOID)jlong_to_ptr(bufferAddress),
1245                                 (DWORD)bufferLength,
1246                                 subtree,
1247                                 (DWORD)filter,
1248                                 (LPDWORD)jlong_to_ptr(bytesReturnedAddress),
1249                                 (LPOVERLAPPED)jlong_to_ptr(pOverlapped),
1250                                 NULL);
1251     if (res == 0) {
1252         throwWindowsException(env, GetLastError());
1253     }
1254 }
1255