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