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 "jni.h" 27 #include "jni_util.h" 28 #include "jvm.h" 29 #include "io_util.h" 30 #include "io_util_md.h" 31 #include <stdio.h> 32 33 #include <wchar.h> 34 #include <io.h> 35 #include <fcntl.h> 36 #include <errno.h> 37 #include <string.h> 38 #include <sys/types.h> 39 #include <sys/stat.h> 40 #include <limits.h> 41 #include <wincon.h> 42 43 static DWORD MAX_INPUT_EVENTS = 2000; 44 45 /* If this returns NULL then an exception is pending */ 46 WCHAR* 47 fileToNTPath(JNIEnv *env, jobject file, jfieldID id) { 48 jstring path = NULL; 49 if (file != NULL) { 50 path = (*env)->GetObjectField(env, file, id); 51 } 52 return pathToNTPath(env, path, JNI_FALSE); 53 } 54 55 /* Returns the working directory for the given drive, or NULL */ 56 WCHAR* 57 currentDir(int di) { 58 UINT dt; 59 WCHAR root[4]; 60 // verify drive is valid as _wgetdcwd in the VC++ 2010 runtime 61 // library does not handle invalid drives. 62 root[0] = L'A' + (WCHAR)(di - 1); 552 HANDLE h = (HANDLE)fd; 553 554 if (whence == SEEK_END) { 555 op = FILE_END; 556 } 557 if (whence == SEEK_CUR) { 558 op = FILE_CURRENT; 559 } 560 if (whence == SEEK_SET) { 561 op = FILE_BEGIN; 562 } 563 564 distance.QuadPart = offset; 565 if (SetFilePointerEx(h, distance, &pos, op) == 0) { 566 return -1; 567 } 568 return long_to_jlong(pos.QuadPart); 569 } 570 571 size_t 572 getLastErrorString(char *buf, size_t len) 573 { 574 DWORD errval; 575 if (len > 0) { 576 if ((errval = GetLastError()) != 0) { 577 // DOS error 578 size_t n = (size_t)FormatMessage( 579 FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 580 NULL, 581 errval, 582 0, 583 buf, 584 (DWORD)len, 585 NULL); 586 if (n > 3) { 587 // Drop final '.', CR, LF 588 if (buf[n - 1] == '\n') n--; 589 if (buf[n - 1] == '\r') n--; 590 if (buf[n - 1] == '.') n--; 591 buf[n] = '\0'; 592 } 593 return n; 594 } 595 596 if (errno != 0) { 597 // C runtime error that has no corresponding DOS error code 598 const char *err = strerror(errno); 599 size_t n = strlen(err); 600 if (n >= len) 601 n = len - 1; 602 603 strncpy(buf, err, n); 604 buf[n] = '\0'; 605 return n; 606 } 607 } 608 609 return 0; 610 } | 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 "jni.h" 27 #include "jni_util.h" 28 #include "jvm.h" 29 #include "io_util.h" 30 #include "io_util_md.h" 31 #include <stdio.h> 32 #include <windows.h> 33 34 #include <wchar.h> 35 #include <io.h> 36 #include <fcntl.h> 37 #include <errno.h> 38 #include <string.h> 39 #include <sys/types.h> 40 #include <sys/stat.h> 41 #include <limits.h> 42 #include <wincon.h> 43 44 45 static DWORD MAX_INPUT_EVENTS = 2000; 46 47 /* If this returns NULL then an exception is pending */ 48 WCHAR* 49 fileToNTPath(JNIEnv *env, jobject file, jfieldID id) { 50 jstring path = NULL; 51 if (file != NULL) { 52 path = (*env)->GetObjectField(env, file, id); 53 } 54 return pathToNTPath(env, path, JNI_FALSE); 55 } 56 57 /* Returns the working directory for the given drive, or NULL */ 58 WCHAR* 59 currentDir(int di) { 60 UINT dt; 61 WCHAR root[4]; 62 // verify drive is valid as _wgetdcwd in the VC++ 2010 runtime 63 // library does not handle invalid drives. 64 root[0] = L'A' + (WCHAR)(di - 1); 554 HANDLE h = (HANDLE)fd; 555 556 if (whence == SEEK_END) { 557 op = FILE_END; 558 } 559 if (whence == SEEK_CUR) { 560 op = FILE_CURRENT; 561 } 562 if (whence == SEEK_SET) { 563 op = FILE_BEGIN; 564 } 565 566 distance.QuadPart = offset; 567 if (SetFilePointerEx(h, distance, &pos, op) == 0) { 568 return -1; 569 } 570 return long_to_jlong(pos.QuadPart); 571 } 572 573 size_t 574 getLastErrorString(char *utf8_jvmErrorMsg, size_t cbErrorMsg) 575 { 576 size_t n = 0; 577 if (cbErrorMsg > 0) { 578 BOOLEAN noError = FALSE; 579 WCHAR *utf16_osErrorMsg = (WCHAR *)malloc(cbErrorMsg*sizeof(WCHAR)); 580 if (utf16_osErrorMsg == NULL) { 581 // OOM accident 582 strncpy(utf8_jvmErrorMsg, "Out of memory", cbErrorMsg); 583 // truncate if too long 584 utf8_jvmErrorMsg[cbErrorMsg - 1] = '\0'; 585 n = strlen(utf8_jvmErrorMsg); 586 } else { 587 DWORD errval = GetLastError(); 588 if (errval != 0) { 589 // WIN32 error 590 n = (size_t)FormatMessageW( 591 FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 592 NULL, 593 errval, 594 0, 595 utf16_osErrorMsg, 596 (DWORD)cbErrorMsg, 597 NULL); 598 if (n > 3) { 599 // Drop final '.', CR, LF 600 if (utf16_osErrorMsg[n - 1] == L'\n') --n; 601 if (utf16_osErrorMsg[n - 1] == L'\r') --n; 602 if (utf16_osErrorMsg[n - 1] == L'.') --n; 603 utf16_osErrorMsg[n] = L'\0'; 604 } 605 } else if (errno != 0) { 606 // C runtime error that has no corresponding WIN32 error code 607 const WCHAR *rtError = _wcserror(errno); 608 if (rtError != NULL) { 609 wcsncpy(utf16_osErrorMsg, rtError, cbErrorMsg); 610 // truncate if too long 611 utf16_osErrorMsg[cbErrorMsg - 1] = L'\0'; 612 n = wcslen(utf16_osErrorMsg); 613 } 614 } else 615 noError = TRUE; //OS has no error to report 616 617 if (!noError) { 618 if (n > 0) { 619 n = WideCharToMultiByte( 620 CP_UTF8, 621 0, 622 utf16_osErrorMsg, 623 n, 624 utf8_jvmErrorMsg, 625 cbErrorMsg, 626 NULL, 627 NULL); 628 629 // no way to die 630 if (n > 0) 631 utf8_jvmErrorMsg[min(cbErrorMsg - 1, n)] = '\0'; 632 } 633 634 if (n <= 0) { 635 strncpy(utf8_jvmErrorMsg, "Secondary error while OS message extraction", cbErrorMsg); 636 // truncate if too long 637 utf8_jvmErrorMsg[cbErrorMsg - 1] = '\0'; 638 n = strlen(utf8_jvmErrorMsg); 639 } 640 } 641 free(utf16_osErrorMsg); 642 } 643 } 644 return n; 645 } |