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