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