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










1276 
1277     res = ReadDirectoryChangesW((HANDLE)jlong_to_ptr(hDirectory),
1278                                 (LPVOID)jlong_to_ptr(bufferAddress),
1279                                 (DWORD)bufferLength,
1280                                 subtree,
1281                                 (DWORD)filter,
1282                                 (LPDWORD)jlong_to_ptr(bytesReturnedAddress),
1283                                 (LPOVERLAPPED)jlong_to_ptr(pOverlapped),
1284                                 NULL);
1285     if (res == 0) {
1286         throwWindowsException(env, GetLastError());
1287     }
1288 }
1289 
1290 JNIEXPORT void JNICALL
1291 Java_sun_nio_fs_WindowsNativeDispatcher_BackupRead0(JNIEnv* env, jclass this,
1292     jlong hFile, jlong bufferAddress, jint bufferSize, jboolean abort,
1293     jlong context, jobject obj)
1294 {
1295     BOOL res;
1296     DWORD bytesTransferred;
1297     BOOL a = (abort == JNI_TRUE) ? TRUE : FALSE;
1298     VOID* pContext = (VOID*)jlong_to_ptr(context);
1299 
1300     res = BackupRead((HANDLE)jlong_to_ptr(hFile),
1301                      (LPBYTE)jlong_to_ptr(bufferAddress),
1302                      (DWORD)bufferSize,
1303                      &bytesTransferred,
1304                      a,
1305                      FALSE,
1306                      &pContext);
1307     if (res == 0) {
1308         throwWindowsException(env, GetLastError());
1309     } else {
1310         (*env)->SetIntField(env, obj, backupResult_bytesTransferred,
1311             bytesTransferred);
1312         (*env)->SetLongField(env, obj, backupResult_context,
1313             ptr_to_jlong(pContext));
1314     }
1315 }
1316 
1317 JNIEXPORT void JNICALL
1318 Java_sun_nio_fs_WindowsNativeDispatcher_BackupSeek(JNIEnv* env, jclass this,
1319     jlong hFile, jlong bytesToSeek, jlong context)
1320 {
1321     BOOL res;
1322     jint lowBytesToSeek = (jint)bytesToSeek;
1323     jint highBytesToSeek = (jint)(bytesToSeek >> 32);
1324     DWORD lowBytesSeeked;
1325     DWORD highBytesSeeked;
1326     VOID* pContext = jlong_to_ptr(context);
1327 
1328     res = BackupSeek((HANDLE)jlong_to_ptr(hFile),
1329                      (DWORD)lowBytesToSeek,
1330                      (DWORD)highBytesToSeek,
1331                      &lowBytesSeeked,
1332                      &highBytesSeeked,
1333                      &pContext);
1334     if (res == 0) {
1335         throwWindowsException(env, GetLastError());
1336     }
1337 }
--- EOF ---