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