1 /*
2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
479 int rc;
480 va_list vl;
481 if (size == 0 || buffer == NULL)
482 return -1;
483 buffer[0] = '\0';
484 va_start(vl, format);
485 rc = vsnprintf(buffer, size, format, vl);
486 va_end(vl);
487 /* force a null terminator, if something is amiss */
488 if (rc < 0) {
489 /* apply ansi semantics */
490 buffer[size - 1] = '\0';
491 return (int)size;
492 } else if (rc == size) {
493 /* force a null terminator */
494 buffer[size - 1] = '\0';
495 }
496 return rc;
497 }
498
499 /* taken from hotspot and slightly adjusted for jli lib;
500 * creates a UNC/ELP path from input 'path'
501 * the return buffer is allocated in C heap and needs to be freed using
502 * JLI_MemFree by the caller.
503 */
504 static wchar_t* create_unc_path(const char* path, errno_t* err) {
505 wchar_t* wpath = NULL;
506 size_t converted_chars = 0;
507 size_t path_len = strlen(path) + 1; /* includes the terminating NULL */
508 if (path[0] == '\\' && path[1] == '\\') {
509 if (path[2] == '?' && path[3] == '\\') {
510 /* if it already has a \\?\ don't do the prefix */
511 wpath = (wchar_t*) JLI_MemAlloc(path_len * sizeof(wchar_t));
512 if (wpath != NULL) {
513 *err = mbstowcs_s(&converted_chars, wpath, path_len, path, path_len);
514 } else {
515 *err = ENOMEM;
516 }
517 } else {
518 /* only UNC pathname includes double slashes here */
519 wpath = (wchar_t*) JLI_MemAlloc((path_len + 7) * sizeof(wchar_t));
520 if (wpath != NULL) {
521 wcscpy(wpath, L"\\\\?\\UNC\0");
522 *err = mbstowcs_s(&converted_chars, &wpath[7], path_len, path, path_len);
523 } else {
524 *err = ENOMEM;
525 }
526 }
527 } else {
528 wpath = (wchar_t*) JLI_MemAlloc((path_len + 4) * sizeof(wchar_t));
529 if (wpath != NULL) {
530 wcscpy(wpath, L"\\\\?\\\0");
531 *err = mbstowcs_s(&converted_chars, &wpath[4], path_len, path, path_len);
532 } else {
533 *err = ENOMEM;
534 }
535 }
536 return wpath;
537 }
538
539 int JLI_Open(const char* name, int flags) {
540 int fd;
541 if (strlen(name) < MAX_PATH) {
542 fd = _open(name, flags);
543 } else {
544 errno_t err = ERROR_SUCCESS;
545 wchar_t* wpath = create_unc_path(name, &err);
546 if (err != ERROR_SUCCESS) {
547 if (wpath != NULL) JLI_MemFree(wpath);
548 errno = err;
549 return -1;
550 }
551 fd = _wopen(wpath, flags);
552 if (fd == -1) {
553 errno = GetLastError();
554 }
|
1 /*
2 * Copyright (c) 1997, 2020, 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
479 int rc;
480 va_list vl;
481 if (size == 0 || buffer == NULL)
482 return -1;
483 buffer[0] = '\0';
484 va_start(vl, format);
485 rc = vsnprintf(buffer, size, format, vl);
486 va_end(vl);
487 /* force a null terminator, if something is amiss */
488 if (rc < 0) {
489 /* apply ansi semantics */
490 buffer[size - 1] = '\0';
491 return (int)size;
492 } else if (rc == size) {
493 /* force a null terminator */
494 buffer[size - 1] = '\0';
495 }
496 return rc;
497 }
498
499 static errno_t convert_to_unicode(const char* path, const wchar_t* prefix, wchar_t** wpath) {
500 int unicode_path_len;
501 size_t prefix_len, wpath_len;
502
503 /*
504 * Get required buffer size to convert to Unicode.
505 * The return value includes the terminating null character.
506 */
507 unicode_path_len = MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
508 path, -1, NULL, 0);
509 if (unicode_path_len == 0) {
510 return EINVAL;
511 }
512
513 prefix_len = wcslen(prefix);
514 wpath_len = prefix_len + unicode_path_len;
515 *wpath = (wchar_t*)JLI_MemAlloc(wpath_len * sizeof(wchar_t));
516 if (*wpath == NULL) {
517 return ENOMEM;
518 }
519
520 wcsncpy(*wpath, prefix, prefix_len);
521 MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
522 path, -1, &((*wpath)[prefix_len]), (int)wpath_len);
523
524 return ERROR_SUCCESS;
525 }
526
527 /* taken from hotspot and slightly adjusted for jli lib;
528 * creates a UNC/ELP path from input 'path'
529 * the return buffer is allocated in C heap and needs to be freed using
530 * JLI_MemFree by the caller.
531 */
532 static wchar_t* create_unc_path(const char* path, errno_t* err) {
533 wchar_t* wpath = NULL;
534 size_t converted_chars = 0;
535 size_t path_len = strlen(path) + 1; /* includes the terminating NULL */
536 if (path[0] == '\\' && path[1] == '\\') {
537 if (path[2] == '?' && path[3] == '\\') {
538 /* if it already has a \\?\ don't do the prefix */
539 *err = convert_to_unicode(path, L"", &wpath);
540 } else {
541 /* only UNC pathname includes double slashes here */
542 *err = convert_to_unicode(path, L"\\\\?\\UNC", &wpath);
543 }
544 } else {
545 *err = convert_to_unicode(path, L"\\\\?\\", &wpath);
546 }
547 return wpath;
548 }
549
550 int JLI_Open(const char* name, int flags) {
551 int fd;
552 if (strlen(name) < MAX_PATH) {
553 fd = _open(name, flags);
554 } else {
555 errno_t err = ERROR_SUCCESS;
556 wchar_t* wpath = create_unc_path(name, &err);
557 if (err != ERROR_SUCCESS) {
558 if (wpath != NULL) JLI_MemFree(wpath);
559 errno = err;
560 return -1;
561 }
562 fd = _wopen(wpath, flags);
563 if (fd == -1) {
564 errno = GetLastError();
565 }
|