Path: blob/master/src/java.base/windows/native/libnio/ch/FileChannelImpl.c
41134 views
/*1* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "jni.h"26#include "jni_util.h"27#include "jvm.h"28#include "jlong.h"29#include <io.h>30#include "nio.h"31#include "nio_util.h"32#include "sun_nio_ch_FileChannelImpl.h"33#include "java_lang_Integer.h"3435#include <Mswsock.h>36#pragma comment(lib, "Mswsock.lib")3738static jfieldID chan_fd; /* id for jobject 'fd' in java.io.FileChannel */3940/**************************************************************41* static method to store field ID's in initializers42* and retrieve the allocation granularity43*/44JNIEXPORT jlong JNICALL45Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)46{47SYSTEM_INFO si;48jint align;49GetSystemInfo(&si);50align = si.dwAllocationGranularity;51chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;");52return align;53}545556/**************************************************************57* Channel58*/5960JNIEXPORT jlong JNICALL61Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,62jint prot, jlong off, jlong len, jboolean map_sync)63{64void *mapAddress = 0;65jint lowOffset = (jint)off;66jint highOffset = (jint)(off >> 32);67jlong maxSize = off + len;68jint lowLen = (jint)(maxSize);69jint highLen = (jint)(maxSize >> 32);70jobject fdo = (*env)->GetObjectField(env, this, chan_fd);71HANDLE fileHandle = (HANDLE)(handleval(env, fdo));72HANDLE mapping;73DWORD mapAccess = FILE_MAP_READ;74DWORD fileProtect = PAGE_READONLY;75DWORD mapError;76BOOL result;7778if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {79fileProtect = PAGE_READONLY;80mapAccess = FILE_MAP_READ;81} else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) {82fileProtect = PAGE_READWRITE;83mapAccess = FILE_MAP_WRITE;84} else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) {85fileProtect = PAGE_WRITECOPY;86mapAccess = FILE_MAP_COPY;87}8889if (map_sync) {90JNU_ThrowInternalError(env, "should never call map on platform where MAP_SYNC is unimplemented");91return IOS_THROWN;92}9394mapping = CreateFileMapping(95fileHandle, /* Handle of file */96NULL, /* Not inheritable */97fileProtect, /* Read and write */98highLen, /* High word of max size */99lowLen, /* Low word of max size */100NULL); /* No name for object */101102if (mapping == NULL) {103JNU_ThrowIOExceptionWithLastError(env, "Map failed");104return IOS_THROWN;105}106107mapAddress = MapViewOfFile(108mapping, /* Handle of file mapping object */109mapAccess, /* Read and write access */110highOffset, /* High word of offset */111lowOffset, /* Low word of offset */112(DWORD)len); /* Number of bytes to map */113mapError = GetLastError();114115result = CloseHandle(mapping);116if (result == 0) {117JNU_ThrowIOExceptionWithLastError(env, "Map failed");118return IOS_THROWN;119}120121if (mapAddress == NULL) {122if (mapError == ERROR_NOT_ENOUGH_MEMORY)123JNU_ThrowOutOfMemoryError(env, "Map failed");124else125JNU_ThrowIOExceptionWithLastError(env, "Map failed");126return IOS_THROWN;127}128129return ptr_to_jlong(mapAddress);130}131132JNIEXPORT jint JNICALL133Java_sun_nio_ch_FileChannelImpl_unmap0(JNIEnv *env, jobject this,134jlong address, jlong len)135{136BOOL result;137void *a = (void *) jlong_to_ptr(address);138139result = UnmapViewOfFile(a);140if (result == 0) {141JNU_ThrowIOExceptionWithLastError(env, "Unmap failed");142return IOS_THROWN;143}144return 0;145}146147JNIEXPORT jlong JNICALL148Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,149jobject srcFD,150jlong position, jlong count,151jobject dstFD)152{153const int PACKET_SIZE = 524288;154155LARGE_INTEGER where;156HANDLE src = (HANDLE)(handleval(env, srcFD));157SOCKET dst = (SOCKET)(fdval(env, dstFD));158DWORD chunkSize = (count > java_lang_Integer_MAX_VALUE) ?159java_lang_Integer_MAX_VALUE : (DWORD)count;160BOOL result;161162where.QuadPart = position;163result = SetFilePointerEx(src, where, &where, FILE_BEGIN);164if (result == 0) {165JNU_ThrowIOExceptionWithLastError(env, "SetFilePointerEx failed");166return IOS_THROWN;167}168169result = TransmitFile(170dst,171src,172chunkSize,173PACKET_SIZE,174NULL,175NULL,176TF_USE_KERNEL_APC177);178if (!result) {179int error = WSAGetLastError();180if (WSAEINVAL == error && count >= 0) {181return IOS_UNSUPPORTED_CASE;182}183if (WSAENOTSOCK == error) {184return IOS_UNSUPPORTED_CASE;185}186JNU_ThrowIOExceptionWithLastError(env, "transfer failed");187return IOS_THROWN;188}189return chunkSize;190}191192193