| /* |
| * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| #include "jni.h" |
| #include "jni_util.h" |
| #include "jvm.h" |
| #include "jlong.h" |
| #include <io.h> |
| #include "nio.h" |
| #include "nio_util.h" |
| #include "sun_nio_ch_FileChannelImpl.h" |
| |
| static jfieldID chan_fd; /* id for jobject 'fd' in java.io.FileChannel */ |
| |
| /************************************************************** |
| * static method to store field ID's in initializers |
| * and retrieve the allocation granularity |
| */ |
| JNIEXPORT jlong JNICALL |
| Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz) |
| { |
| SYSTEM_INFO si; |
| jint align; |
| GetSystemInfo(&si); |
| align = si.dwAllocationGranularity; |
| chan_fd = (*env)->GetFieldID(env, clazz, "fd", "Ljava/io/FileDescriptor;"); |
| return align; |
| } |
| |
| |
| /************************************************************** |
| * Channel |
| */ |
| |
| JNIEXPORT jlong JNICALL |
| Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this, |
| jint prot, jlong off, jlong len) |
| { |
| void *mapAddress = 0; |
| jint lowOffset = (jint)off; |
| jint highOffset = (jint)(off >> 32); |
| jlong maxSize = off + len; |
| jint lowLen = (jint)(maxSize); |
| jint highLen = (jint)(maxSize >> 32); |
| jobject fdo = (*env)->GetObjectField(env, this, chan_fd); |
| HANDLE fileHandle = (HANDLE)(handleval(env, fdo)); |
| HANDLE mapping; |
| DWORD mapAccess = FILE_MAP_READ; |
| DWORD fileProtect = PAGE_READONLY; |
| DWORD mapError; |
| BOOL result; |
| |
| if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) { |
| fileProtect = PAGE_READONLY; |
| mapAccess = FILE_MAP_READ; |
| } else if (prot == sun_nio_ch_FileChannelImpl_MAP_RW) { |
| fileProtect = PAGE_READWRITE; |
| mapAccess = FILE_MAP_WRITE; |
| } else if (prot == sun_nio_ch_FileChannelImpl_MAP_PV) { |
| fileProtect = PAGE_WRITECOPY; |
| mapAccess = FILE_MAP_COPY; |
| } |
| |
| mapping = CreateFileMapping( |
| fileHandle, /* Handle of file */ |
| NULL, /* Not inheritable */ |
| fileProtect, /* Read and write */ |
| highLen, /* High word of max size */ |
| lowLen, /* Low word of max size */ |
| NULL); /* No name for object */ |
| |
| if (mapping == NULL) { |
| JNU_ThrowIOExceptionWithLastError(env, "Map failed"); |
| return IOS_THROWN; |
| } |
| |
| mapAddress = MapViewOfFile( |
| mapping, /* Handle of file mapping object */ |
| mapAccess, /* Read and write access */ |
| highOffset, /* High word of offset */ |
| lowOffset, /* Low word of offset */ |
| (DWORD)len); /* Number of bytes to map */ |
| mapError = GetLastError(); |
| |
| result = CloseHandle(mapping); |
| if (result == 0) { |
| JNU_ThrowIOExceptionWithLastError(env, "Map failed"); |
| return IOS_THROWN; |
| } |
| |
| if (mapAddress == NULL) { |
| if (mapError == ERROR_NOT_ENOUGH_MEMORY) |
| JNU_ThrowOutOfMemoryError(env, "Map failed"); |
| else |
| JNU_ThrowIOExceptionWithLastError(env, "Map failed"); |
| return IOS_THROWN; |
| } |
| |
| return ptr_to_jlong(mapAddress); |
| } |
| |
| JNIEXPORT jint JNICALL |
| Java_sun_nio_ch_FileChannelImpl_unmap0(JNIEnv *env, jobject this, |
| jlong address, jlong len) |
| { |
| BOOL result; |
| void *a = (void *) jlong_to_ptr(address); |
| |
| result = UnmapViewOfFile(a); |
| if (result == 0) { |
| JNU_ThrowIOExceptionWithLastError(env, "Unmap failed"); |
| return IOS_THROWN; |
| } |
| return 0; |
| } |
| |
| JNIEXPORT jlong JNICALL |
| Java_sun_nio_ch_FileChannelImpl_position0(JNIEnv *env, jobject this, |
| jobject fdo, jlong offset) |
| { |
| DWORD lowPos = 0; |
| long highPos = 0; |
| HANDLE h = (HANDLE)(handleval(env, fdo)); |
| |
| if (offset < 0) { |
| lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT); |
| } else { |
| lowPos = (DWORD)offset; |
| highPos = (long)(offset >> 32); |
| lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN); |
| } |
| if (lowPos == ((DWORD)-1)) { |
| if (GetLastError() != ERROR_SUCCESS) { |
| JNU_ThrowIOExceptionWithLastError(env, "Seek failed"); |
| return IOS_THROWN; |
| } |
| } |
| return (((jlong)highPos) << 32) | lowPos; |
| } |
| |
| JNIEXPORT void JNICALL |
| Java_sun_nio_ch_FileChannelImpl_close0(JNIEnv *env, jobject this, jobject fdo) |
| { |
| HANDLE h = (HANDLE)(handleval(env, fdo)); |
| if (h != INVALID_HANDLE_VALUE) { |
| jint result = CloseHandle(h); |
| if (result < 0) { |
| JNU_ThrowIOExceptionWithLastError(env, "Close failed"); |
| } |
| } |
| } |
| |
| JNIEXPORT jlong JNICALL |
| Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this, |
| jint srcFD, |
| jlong position, jlong count, |
| jint dstFD) |
| { |
| return IOS_UNSUPPORTED; |
| } |