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 if (MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
522 path, -1, &((*wpath)[prefix_len]), (int)wpath_len) == 0) {
523 JLI_MemFree(*wpath);
524 return EINVAL;
525 }
526
527 return ERROR_SUCCESS;
528 }
529
530 /* taken from hotspot and slightly adjusted for jli lib;
531 * creates a UNC/ELP path from input 'path'
532 * the return buffer is allocated in C heap and needs to be freed using
533 * JLI_MemFree by the caller.
534 */
535 static wchar_t* create_unc_path(const char* path, errno_t* err) {
536 wchar_t* wpath = NULL;
537 size_t converted_chars = 0;
538 size_t path_len = strlen(path) + 1; /* includes the terminating NULL */
539 if (path[0] == '\\' && path[1] == '\\') {
540 if (path[2] == '?' && path[3] == '\\') {
541 /* if it already has a \\?\ don't do the prefix */
542 *err = convert_to_unicode(path, L"", &wpath);
543 } else {
544 /* only UNC pathname includes double slashes here */
545 *err = convert_to_unicode(path, L"\\\\?\\UNC", &wpath);
546 }
547 } else {
548 *err = convert_to_unicode(path, L"\\\\?\\", &wpath);
549 }
550 return wpath;
551 }
552
553 int JLI_Open(const char* name, int flags) {
554 int fd;
555 if (strlen(name) < MAX_PATH) {
556 fd = _open(name, flags);
557 } else {
558 errno_t err = ERROR_SUCCESS;
559 wchar_t* wpath = create_unc_path(name, &err);
560 if (err != ERROR_SUCCESS) {
561 if (wpath != NULL) JLI_MemFree(wpath);
562 errno = err;
563 return -1;
564 }
565 fd = _wopen(wpath, flags);
566 if (fd == -1) {
567 errno = GetLastError();
568 }
|