1 /*
   2  * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #ifndef _WIN32_WINNT
  27 #define _WIN32_WINNT 0x0501
  28 #endif
  29 
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <ctype.h>
  33 #include <direct.h>
  34 #include <malloc.h>
  35 #include <io.h>
  36 #include <windows.h>
  37 #include <aclapi.h>
  38 #include <winioctl.h>
  39 #include <Sddl.h>
  40 
  41 #include "jni.h"
  42 #include "jni_util.h"
  43 #include "jlong.h"
  44 
  45 #include "sun_nio_fs_WindowsNativeDispatcher.h"
  46 
  47 /**
  48  * jfieldIDs
  49  */
  50 static jfieldID findFirst_handle;
  51 static jfieldID findFirst_name;
  52 static jfieldID findFirst_attributes;
  53 
  54 static jfieldID findStream_handle;
  55 static jfieldID findStream_name;
  56 
  57 static jfieldID volumeInfo_fsName;
  58 static jfieldID volumeInfo_volName;
  59 static jfieldID volumeInfo_volSN;
  60 static jfieldID volumeInfo_flags;
  61 
  62 static jfieldID diskSpace_bytesAvailable;
  63 static jfieldID diskSpace_totalBytes;
  64 static jfieldID diskSpace_totalFree;
  65 
  66 static jfieldID account_domain;
  67 static jfieldID account_name;
  68 static jfieldID account_use;
  69 
  70 static jfieldID aclInfo_aceCount;
  71 
  72 static jfieldID completionStatus_error;
  73 static jfieldID completionStatus_bytesTransferred;
  74 static jfieldID completionStatus_completionKey;
  75 
  76 static jfieldID backupResult_bytesTransferred;
  77 static jfieldID backupResult_context;
  78 
  79 
  80 /**
  81  * Win32 APIs not available in Windows XP
  82  */
  83 typedef HANDLE (WINAPI* FindFirstStream_Proc)(LPCWSTR, STREAM_INFO_LEVELS, LPVOID, DWORD);
  84 typedef BOOL (WINAPI* FindNextStream_Proc)(HANDLE, LPVOID);
  85 
  86 typedef BOOLEAN (WINAPI* CreateSymbolicLinkProc) (LPCWSTR, LPCWSTR, DWORD);
  87 typedef BOOL (WINAPI* GetFinalPathNameByHandleProc) (HANDLE, LPWSTR, DWORD, DWORD);
  88 
  89 static FindFirstStream_Proc FindFirstStream_func;
  90 static FindNextStream_Proc FindNextStream_func;
  91 
  92 static CreateSymbolicLinkProc CreateSymbolicLink_func;
  93 static GetFinalPathNameByHandleProc GetFinalPathNameByHandle_func;
  94 
  95 static void throwWindowsException(JNIEnv* env, DWORD lastError) {
  96     jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
  97         "(I)V", lastError);
  98     if (x != NULL) {
  99         (*env)->Throw(env, x);
 100     }
 101 }
 102 
 103 /**
 104  * Initializes jfieldIDs and get address of Win32 calls that are located
 105  * at runtime.
 106  */
 107 JNIEXPORT void JNICALL
 108 Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
 109 {
 110     jclass clazz;
 111     HMODULE h;
 112 
 113     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstFile");
 114     CHECK_NULL(clazz);
 115     findFirst_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
 116     CHECK_NULL(findFirst_handle);
 117     findFirst_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
 118     CHECK_NULL(findFirst_name);
 119     findFirst_attributes = (*env)->GetFieldID(env, clazz, "attributes", "I");
 120     CHECK_NULL(findFirst_attributes);
 121 
 122     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstStream");
 123     CHECK_NULL(clazz);
 124     findStream_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
 125     CHECK_NULL(findStream_handle);
 126     findStream_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
 127     CHECK_NULL(findStream_name);
 128 
 129     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$VolumeInformation");
 130     CHECK_NULL(clazz);
 131     volumeInfo_fsName = (*env)->GetFieldID(env, clazz, "fileSystemName", "Ljava/lang/String;");
 132     CHECK_NULL(volumeInfo_fsName);
 133     volumeInfo_volName = (*env)->GetFieldID(env, clazz, "volumeName", "Ljava/lang/String;");
 134     CHECK_NULL(volumeInfo_volName);
 135     volumeInfo_volSN = (*env)->GetFieldID(env, clazz, "volumeSerialNumber", "I");
 136     CHECK_NULL(volumeInfo_volSN);
 137     volumeInfo_flags = (*env)->GetFieldID(env, clazz, "flags", "I");
 138     CHECK_NULL(volumeInfo_flags);
 139 
 140     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$DiskFreeSpace");
 141     CHECK_NULL(clazz);
 142     diskSpace_bytesAvailable = (*env)->GetFieldID(env, clazz, "freeBytesAvailable", "J");
 143     CHECK_NULL(diskSpace_bytesAvailable);
 144     diskSpace_totalBytes = (*env)->GetFieldID(env, clazz, "totalNumberOfBytes", "J");
 145     CHECK_NULL(diskSpace_totalBytes);
 146     diskSpace_totalFree = (*env)->GetFieldID(env, clazz, "totalNumberOfFreeBytes", "J");
 147     CHECK_NULL(diskSpace_totalFree);
 148 
 149     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$Account");
 150     CHECK_NULL(clazz);
 151     account_domain = (*env)->GetFieldID(env, clazz, "domain", "Ljava/lang/String;");
 152     CHECK_NULL(account_domain);
 153     account_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
 154     CHECK_NULL(account_name);
 155     account_use = (*env)->GetFieldID(env, clazz, "use", "I");
 156     CHECK_NULL(account_use);
 157 
 158     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$AclInformation");
 159     CHECK_NULL(clazz);
 160     aclInfo_aceCount = (*env)->GetFieldID(env, clazz, "aceCount", "I");
 161     CHECK_NULL(aclInfo_aceCount);
 162 
 163     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$CompletionStatus");
 164     CHECK_NULL(clazz);
 165     completionStatus_error = (*env)->GetFieldID(env, clazz, "error", "I");
 166     CHECK_NULL(completionStatus_error);
 167     completionStatus_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
 168     CHECK_NULL(completionStatus_bytesTransferred);
 169     completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "J");
 170     CHECK_NULL(completionStatus_completionKey);
 171 
 172     clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$BackupResult");
 173     CHECK_NULL(clazz);
 174     backupResult_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
 175     CHECK_NULL(backupResult_bytesTransferred);
 176     backupResult_context = (*env)->GetFieldID(env, clazz, "context", "J");
 177     CHECK_NULL(backupResult_context);
 178 
 179     // get handle to kernel32
 180     if (GetModuleHandleExW((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
 181                             GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
 182                            (LPCWSTR)&CreateFileW, &h) != 0)
 183     {
 184         // requires Windows Server 2003 or newer
 185         FindFirstStream_func =
 186             (FindFirstStream_Proc)GetProcAddress(h, "FindFirstStreamW");
 187         FindNextStream_func =
 188             (FindNextStream_Proc)GetProcAddress(h, "FindNextStreamW");
 189 
 190         // requires Windows Vista or newer
 191         CreateSymbolicLink_func =
 192             (CreateSymbolicLinkProc)GetProcAddress(h, "CreateSymbolicLinkW");
 193         GetFinalPathNameByHandle_func =
 194             (GetFinalPathNameByHandleProc)GetProcAddress(h, "GetFinalPathNameByHandleW");
 195     }
 196 }
 197 











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

























1233 Java_sun_nio_fs_WindowsNativeDispatcher_ReadDirectoryChangesW(JNIEnv* env, jclass this,
1234     jlong hDirectory, jlong bufferAddress, jint bufferLength, jboolean watchSubTree, jint filter,
1235     jlong bytesReturnedAddress, jlong pOverlapped)
1236 {
1237     BOOL res;
1238     BOOL subtree = (watchSubTree == JNI_TRUE) ? TRUE : FALSE;
1239 
1240     /* Any unused members of [OVERLAPPED] structure should always be initialized to zero
1241        before the structure is used in a function call.
1242        Otherwise, the function may fail and return ERROR_INVALID_PARAMETER.
1243        http://msdn.microsoft.com/en-us/library/windows/desktop/ms684342%28v=vs.85%29.aspx
1244 
1245        The [Offset] and [OffsetHigh] members of this structure are not used.
1246        http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465%28v=vs.85%29.aspx
1247 
1248        [hEvent] should be zero, other fields are the return values. */
1249     ZeroMemory((LPOVERLAPPED)jlong_to_ptr(pOverlapped), sizeof(OVERLAPPED));
1250 
1251     res = ReadDirectoryChangesW((HANDLE)jlong_to_ptr(hDirectory),
1252                                 (LPVOID)jlong_to_ptr(bufferAddress),
1253                                 (DWORD)bufferLength,
1254                                 subtree,
1255                                 (DWORD)filter,
1256                                 (LPDWORD)jlong_to_ptr(bytesReturnedAddress),
1257                                 (LPOVERLAPPED)jlong_to_ptr(pOverlapped),
1258                                 NULL);
1259     if (res == 0) {
1260         throwWindowsException(env, GetLastError());
1261     }
1262 }
1263 
1264 JNIEXPORT void JNICALL
1265 Java_sun_nio_fs_WindowsNativeDispatcher_BackupRead0(JNIEnv* env, jclass this,
1266     jlong hFile, jlong bufferAddress, jint bufferSize, jboolean abort,
1267     jlong context, jobject obj)
1268 {
1269     BOOL res;
1270     DWORD bytesTransferred;
1271     BOOL a = (abort == JNI_TRUE) ? TRUE : FALSE;
1272     VOID* pContext = (VOID*)jlong_to_ptr(context);
1273 
1274     res = BackupRead((HANDLE)jlong_to_ptr(hFile),
1275                      (LPBYTE)jlong_to_ptr(bufferAddress),
1276                      (DWORD)bufferSize,
1277                      &bytesTransferred,
1278                      a,
1279                      FALSE,
1280                      &pContext);
1281     if (res == 0) {
1282         throwWindowsException(env, GetLastError());
1283     } else {
1284         (*env)->SetIntField(env, obj, backupResult_bytesTransferred,
1285             bytesTransferred);
1286         (*env)->SetLongField(env, obj, backupResult_context,
1287             ptr_to_jlong(pContext));
1288     }
1289 }
1290 
1291 JNIEXPORT void JNICALL
1292 Java_sun_nio_fs_WindowsNativeDispatcher_BackupSeek(JNIEnv* env, jclass this,
1293     jlong hFile, jlong bytesToSeek, jlong context)
1294 {
1295     BOOL res;
1296     jint lowBytesToSeek = (jint)bytesToSeek;
1297     jint highBytesToSeek = (jint)(bytesToSeek >> 32);
1298     DWORD lowBytesSeeked;
1299     DWORD highBytesSeeked;
1300     VOID* pContext = jlong_to_ptr(context);
1301 
1302     res = BackupSeek((HANDLE)jlong_to_ptr(hFile),
1303                      (DWORD)lowBytesToSeek,
1304                      (DWORD)highBytesToSeek,
1305                      &lowBytesSeeked,
1306                      &highBytesSeeked,
1307                      &pContext);
1308     if (res == 0) {
1309         throwWindowsException(env, GetLastError());
1310     }
1311 }
--- EOF ---