0N/A/*
3261N/A * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#include <windows.h>
0N/A#include "jni.h"
0N/A#include "jni_util.h"
0N/A#include "jvm.h"
0N/A#include "jlong.h"
893N/A#include "sun_nio_ch_FileDispatcherImpl.h"
0N/A#include <io.h>
0N/A#include "nio.h"
0N/A#include "nio_util.h"
2984N/A#include "jlong.h"
0N/A
0N/A
0N/A/**************************************************************
893N/A * FileDispatcherImpl.c
0N/A */
0N/A
0N/AJNIEXPORT jint JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz, jobject fdo,
0N/A jlong address, jint len)
0N/A{
0N/A DWORD read = 0;
0N/A BOOL result = 0;
0N/A HANDLE h = (HANDLE)(handleval(env, fdo));
0N/A
0N/A if (h == INVALID_HANDLE_VALUE) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");
0N/A return IOS_THROWN;
0N/A }
0N/A result = ReadFile(h, /* File handle to read */
0N/A (LPVOID)address, /* address to put data */
0N/A len, /* number of bytes to read */
0N/A &read, /* number of bytes read */
0N/A NULL); /* no overlapped struct */
0N/A if (result == 0) {
0N/A int error = GetLastError();
0N/A if (error == ERROR_BROKEN_PIPE) {
0N/A return IOS_EOF;
0N/A }
0N/A if (error == ERROR_NO_DATA) {
0N/A return IOS_UNAVAILABLE;
0N/A }
0N/A JNU_ThrowIOExceptionWithLastError(env, "Read failed");
0N/A return IOS_THROWN;
0N/A }
0N/A return convertReturnVal(env, (jint)read, JNI_TRUE);
0N/A}
0N/A
0N/AJNIEXPORT jlong JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz, jobject fdo,
0N/A jlong address, jint len)
0N/A{
0N/A DWORD read = 0;
0N/A BOOL result = 0;
0N/A jlong totalRead = 0;
0N/A LPVOID loc;
0N/A int i = 0;
0N/A DWORD num = 0;
0N/A struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);
0N/A HANDLE h = (HANDLE)(handleval(env, fdo));
0N/A
0N/A if (h == INVALID_HANDLE_VALUE) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");
0N/A return IOS_THROWN;
0N/A }
0N/A
0N/A for(i=0; i<len; i++) {
0N/A loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);
0N/A num = iovecp[i].iov_len;
0N/A result = ReadFile(h, /* File handle to read */
0N/A loc, /* address to put data */
0N/A num, /* number of bytes to read */
0N/A &read, /* number of bytes read */
0N/A NULL); /* no overlapped struct */
0N/A if (read > 0) {
0N/A totalRead += read;
0N/A }
0N/A if (read < num) {
0N/A break;
0N/A }
0N/A }
0N/A
0N/A if (result == 0) {
0N/A int error = GetLastError();
0N/A if (error == ERROR_BROKEN_PIPE) {
0N/A return IOS_EOF;
0N/A }
0N/A if (error == ERROR_NO_DATA) {
0N/A return IOS_UNAVAILABLE;
0N/A }
0N/A JNU_ThrowIOExceptionWithLastError(env, "Read failed");
0N/A return IOS_THROWN;
0N/A }
0N/A
0N/A return convertLongReturnVal(env, totalRead, JNI_TRUE);
0N/A}
0N/A
0N/AJNIEXPORT jint JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo,
0N/A jlong address, jint len, jlong offset)
0N/A{
0N/A DWORD read = 0;
0N/A BOOL result = 0;
0N/A HANDLE h = (HANDLE)(handleval(env, fdo));
0N/A DWORD lowPos = 0;
0N/A long highPos = 0;
0N/A DWORD lowOffset = 0;
0N/A long highOffset = 0;
0N/A
0N/A if (h == INVALID_HANDLE_VALUE) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");
0N/A return IOS_THROWN;
0N/A }
0N/A
0N/A lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);
0N/A if (lowPos == ((DWORD)-1)) {
0N/A if (GetLastError() != ERROR_SUCCESS) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
0N/A return IOS_THROWN;
0N/A }
0N/A }
0N/A
0N/A lowOffset = (DWORD)offset;
0N/A highOffset = (DWORD)(offset >> 32);
0N/A lowOffset = SetFilePointer(h, lowOffset, &highOffset, FILE_BEGIN);
0N/A if (lowOffset == ((DWORD)-1)) {
0N/A if (GetLastError() != ERROR_SUCCESS) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
0N/A return IOS_THROWN;
0N/A }
0N/A }
0N/A
0N/A result = ReadFile(h, /* File handle to read */
0N/A (LPVOID)address, /* address to put data */
0N/A len, /* number of bytes to read */
0N/A &read, /* number of bytes read */
0N/A NULL); /* struct with offset */
0N/A
0N/A if (result == 0) {
0N/A int error = GetLastError();
0N/A if (error == ERROR_BROKEN_PIPE) {
0N/A return IOS_EOF;
0N/A }
0N/A if (error == ERROR_NO_DATA) {
0N/A return IOS_UNAVAILABLE;
0N/A }
0N/A JNU_ThrowIOExceptionWithLastError(env, "Read failed");
0N/A return IOS_THROWN;
0N/A }
0N/A
0N/A lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);
0N/A if (lowPos == ((DWORD)-1)) {
0N/A if (GetLastError() != ERROR_SUCCESS) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
0N/A return IOS_THROWN;
0N/A }
0N/A }
0N/A return convertReturnVal(env, (jint)read, JNI_TRUE);
0N/A}
0N/A
0N/AJNIEXPORT jint JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz, jobject fdo,
3200N/A jlong address, jint len, jboolean append)
0N/A{
0N/A BOOL result = 0;
0N/A DWORD written = 0;
0N/A HANDLE h = (HANDLE)(handleval(env, fdo));
0N/A
0N/A if (h != INVALID_HANDLE_VALUE) {
3200N/A OVERLAPPED ov;
3200N/A LPOVERLAPPED lpOv;
3200N/A if (append == JNI_TRUE) {
3200N/A ov.Offset = (DWORD)0xFFFFFFFF;
3200N/A ov.OffsetHigh = (DWORD)0xFFFFFFFF;
3200N/A ov.hEvent = NULL;
3200N/A lpOv = &ov;
3200N/A } else {
3200N/A lpOv = NULL;
3200N/A }
0N/A result = WriteFile(h, /* File handle to write */
0N/A (LPCVOID)address, /* pointers to the buffers */
0N/A len, /* number of bytes to write */
0N/A &written, /* receives number of bytes written */
3200N/A lpOv); /* overlapped struct */
0N/A }
0N/A
0N/A if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Write failed");
0N/A }
0N/A
0N/A return convertReturnVal(env, (jint)written, JNI_FALSE);
0N/A}
0N/A
0N/AJNIEXPORT jlong JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz, jobject fdo,
3200N/A jlong address, jint len, jboolean append)
0N/A{
0N/A BOOL result = 0;
0N/A DWORD written = 0;
0N/A HANDLE h = (HANDLE)(handleval(env, fdo));
0N/A jlong totalWritten = 0;
0N/A
0N/A if (h != INVALID_HANDLE_VALUE) {
0N/A LPVOID loc;
0N/A int i = 0;
0N/A DWORD num = 0;
0N/A struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);
3200N/A OVERLAPPED ov;
3200N/A LPOVERLAPPED lpOv;
3200N/A if (append == JNI_TRUE) {
3200N/A ov.Offset = (DWORD)0xFFFFFFFF;
3200N/A ov.OffsetHigh = (DWORD)0xFFFFFFFF;
3200N/A ov.hEvent = NULL;
3200N/A lpOv = &ov;
3200N/A } else {
3200N/A lpOv = NULL;
3200N/A }
0N/A for(i=0; i<len; i++) {
0N/A loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);
0N/A num = iovecp[i].iov_len;
0N/A result = WriteFile(h, /* File handle to write */
0N/A loc, /* pointers to the buffers */
0N/A num, /* number of bytes to write */
0N/A &written,/* receives number of bytes written */
3200N/A lpOv); /* overlapped struct */
0N/A if (written > 0) {
0N/A totalWritten += written;
0N/A }
0N/A if (written < num) {
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A
0N/A if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Write failed");
0N/A }
0N/A
0N/A return convertLongReturnVal(env, totalWritten, JNI_FALSE);
0N/A}
0N/A
0N/AJNIEXPORT jint JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,
0N/A jlong address, jint len, jlong offset)
0N/A{
0N/A BOOL result = 0;
0N/A DWORD written = 0;
0N/A HANDLE h = (HANDLE)(handleval(env, fdo));
0N/A DWORD lowPos = 0;
0N/A long highPos = 0;
0N/A DWORD lowOffset = 0;
0N/A long highOffset = 0;
0N/A
0N/A lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);
0N/A if (lowPos == ((DWORD)-1)) {
0N/A if (GetLastError() != ERROR_SUCCESS) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
0N/A return IOS_THROWN;
0N/A }
0N/A }
0N/A
0N/A lowOffset = (DWORD)offset;
0N/A highOffset = (DWORD)(offset >> 32);
0N/A lowOffset = SetFilePointer(h, lowOffset, &highOffset, FILE_BEGIN);
0N/A if (lowOffset == ((DWORD)-1)) {
0N/A if (GetLastError() != ERROR_SUCCESS) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
0N/A return IOS_THROWN;
0N/A }
0N/A }
0N/A
0N/A result = WriteFile(h, /* File handle to write */
0N/A (LPCVOID)address, /* pointers to the buffers */
0N/A len, /* number of bytes to write */
0N/A &written, /* receives number of bytes written */
0N/A NULL); /* no overlapped struct */
0N/A
0N/A if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Write failed");
0N/A return IOS_THROWN;
0N/A }
0N/A
0N/A lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);
0N/A if (lowPos == ((DWORD)-1)) {
0N/A if (GetLastError() != ERROR_SUCCESS) {
0N/A JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
0N/A return IOS_THROWN;
0N/A }
0N/A }
0N/A
0N/A return convertReturnVal(env, (jint)written, JNI_FALSE);
0N/A}
0N/A
893N/AJNIEXPORT jint JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
893N/A jobject fdo, jboolean md)
893N/A{
893N/A int result = 0;
893N/A HANDLE h = (HANDLE)(handleval(env, fdo));
893N/A
893N/A if (h != INVALID_HANDLE_VALUE) {
893N/A result = FlushFileBuffers(h);
893N/A if (result == 0) {
893N/A int error = GetLastError();
893N/A if (error != ERROR_ACCESS_DENIED) {
893N/A JNU_ThrowIOExceptionWithLastError(env, "Force failed");
893N/A return IOS_THROWN;
893N/A }
893N/A }
893N/A } else {
893N/A JNU_ThrowIOExceptionWithLastError(env, "Force failed");
893N/A return IOS_THROWN;
893N/A }
893N/A return 0;
893N/A}
893N/A
893N/AJNIEXPORT jint JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,
893N/A jobject fdo, jlong size)
893N/A{
893N/A DWORD lowPos = 0;
893N/A long highPos = 0;
893N/A BOOL result = 0;
893N/A HANDLE h = (HANDLE)(handleval(env, fdo));
893N/A
893N/A lowPos = (DWORD)size;
893N/A highPos = (long)(size >> 32);
893N/A lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);
893N/A if (lowPos == ((DWORD)-1)) {
893N/A if (GetLastError() != ERROR_SUCCESS) {
893N/A JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
893N/A return IOS_THROWN;
893N/A }
893N/A }
893N/A result = SetEndOfFile(h);
893N/A if (result == 0) {
893N/A JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
893N/A return IOS_THROWN;
893N/A }
893N/A return 0;
893N/A}
893N/A
893N/AJNIEXPORT jlong JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
893N/A{
893N/A DWORD sizeLow = 0;
893N/A DWORD sizeHigh = 0;
893N/A HANDLE h = (HANDLE)(handleval(env, fdo));
893N/A
893N/A sizeLow = GetFileSize(h, &sizeHigh);
893N/A if (sizeLow == ((DWORD)-1)) {
893N/A if (GetLastError() != ERROR_SUCCESS) {
893N/A JNU_ThrowIOExceptionWithLastError(env, "Size failed");
893N/A return IOS_THROWN;
893N/A }
893N/A }
893N/A return (((jlong)sizeHigh) << 32) | sizeLow;
893N/A}
893N/A
893N/AJNIEXPORT jint JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
893N/A jboolean block, jlong pos, jlong size,
893N/A jboolean shared)
893N/A{
893N/A HANDLE h = (HANDLE)(handleval(env, fdo));
893N/A DWORD lowPos = (DWORD)pos;
893N/A long highPos = (long)(pos >> 32);
893N/A DWORD lowNumBytes = (DWORD)size;
893N/A DWORD highNumBytes = (DWORD)(size >> 32);
893N/A BOOL result;
893N/A DWORD flags = 0;
893N/A OVERLAPPED o;
893N/A o.hEvent = 0;
893N/A o.Offset = lowPos;
893N/A o.OffsetHigh = highPos;
893N/A if (block == JNI_FALSE) {
893N/A flags |= LOCKFILE_FAIL_IMMEDIATELY;
893N/A }
893N/A if (shared == JNI_FALSE) {
893N/A flags |= LOCKFILE_EXCLUSIVE_LOCK;
893N/A }
893N/A result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o);
893N/A if (result == 0) {
893N/A int error = GetLastError();
893N/A if (error != ERROR_LOCK_VIOLATION) {
893N/A JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
893N/A return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
893N/A }
893N/A if (flags & LOCKFILE_FAIL_IMMEDIATELY) {
893N/A return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
893N/A }
893N/A JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
893N/A return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
893N/A }
893N/A return sun_nio_ch_FileDispatcherImpl_LOCKED;
893N/A}
893N/A
893N/AJNIEXPORT void JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_release0(JNIEnv *env, jobject this,
893N/A jobject fdo, jlong pos, jlong size)
893N/A{
893N/A HANDLE h = (HANDLE)(handleval(env, fdo));
893N/A DWORD lowPos = (DWORD)pos;
893N/A long highPos = (long)(pos >> 32);
893N/A DWORD lowNumBytes = (DWORD)size;
893N/A DWORD highNumBytes = (DWORD)(size >> 32);
893N/A jint result = 0;
893N/A OVERLAPPED o;
893N/A o.hEvent = 0;
893N/A o.Offset = lowPos;
893N/A o.OffsetHigh = highPos;
893N/A result = UnlockFileEx(h, 0, lowNumBytes, highNumBytes, &o);
1109N/A if (result == 0 && GetLastError() != ERROR_NOT_LOCKED) {
893N/A JNU_ThrowIOExceptionWithLastError(env, "Release failed");
893N/A }
893N/A}
893N/A
0N/Astatic void closeFile(JNIEnv *env, jlong fd) {
0N/A HANDLE h = (HANDLE)fd;
0N/A if (h != INVALID_HANDLE_VALUE) {
0N/A int result = CloseHandle(h);
0N/A if (result < 0)
0N/A JNU_ThrowIOExceptionWithLastError(env, "Close failed");
0N/A }
0N/A}
0N/A
0N/AJNIEXPORT void JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_close0(JNIEnv *env, jclass clazz, jobject fdo)
0N/A{
0N/A jlong fd = handleval(env, fdo);
0N/A closeFile(env, fd);
0N/A}
0N/A
0N/AJNIEXPORT void JNICALL
893N/AJava_sun_nio_ch_FileDispatcherImpl_closeByHandle(JNIEnv *env, jclass clazz,
0N/A jlong fd)
0N/A{
0N/A closeFile(env, fd);
0N/A}
2984N/A
2984N/AJNIEXPORT jlong JNICALL
3200N/AJava_sun_nio_ch_FileDispatcherImpl_duplicateHandle(JNIEnv *env, jclass this, jlong handle)
2984N/A{
2984N/A HANDLE hProcess = GetCurrentProcess();
3200N/A HANDLE hFile = jlong_to_ptr(handle);
2984N/A HANDLE hResult;
2984N/A BOOL res = DuplicateHandle(hProcess, hFile, hProcess, &hResult, 0, FALSE,
2984N/A DUPLICATE_SAME_ACCESS);
2984N/A if (res == 0)
2984N/A JNU_ThrowIOExceptionWithLastError(env, "DuplicateHandle failed");
2984N/A return ptr_to_jlong(hResult);
2984N/A}