Path: blob/master/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c
41134 views
/*1* Copyright (c) 2000, 2018, 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 <windows.h>26#include "jni.h"27#include "jni_util.h"28#include "jvm.h"29#include "jlong.h"30#include "sun_nio_ch_FileDispatcherImpl.h"31#include <io.h>32#include "nio.h"33#include "nio_util.h"34#include "jlong.h"353637/**************************************************************38* FileDispatcherImpl.c39*/4041JNIEXPORT jint JNICALL42Java_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz, jobject fdo,43jlong address, jint len)44{45DWORD read = 0;46BOOL result = 0;47HANDLE h = (HANDLE)(handleval(env, fdo));4849if (h == INVALID_HANDLE_VALUE) {50JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");51return IOS_THROWN;52}53result = ReadFile(h, /* File handle to read */54(LPVOID)address, /* address to put data */55len, /* number of bytes to read */56&read, /* number of bytes read */57NULL); /* no overlapped struct */58if (result == 0) {59int error = GetLastError();60if (error == ERROR_BROKEN_PIPE) {61return IOS_EOF;62}63if (error == ERROR_NO_DATA) {64return IOS_UNAVAILABLE;65}66JNU_ThrowIOExceptionWithLastError(env, "Read failed");67return IOS_THROWN;68}69return convertReturnVal(env, (jint)read, JNI_TRUE);70}7172JNIEXPORT jlong JNICALL73Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz, jobject fdo,74jlong address, jint len)75{76DWORD read = 0;77BOOL result = 0;78jlong totalRead = 0;79LPVOID loc;80int i = 0;81DWORD num = 0;82struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);83HANDLE h = (HANDLE)(handleval(env, fdo));8485if (h == INVALID_HANDLE_VALUE) {86JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");87return IOS_THROWN;88}8990for(i=0; i<len; i++) {91loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);92num = iovecp[i].iov_len;93result = ReadFile(h, /* File handle to read */94loc, /* address to put data */95num, /* number of bytes to read */96&read, /* number of bytes read */97NULL); /* no overlapped struct */98if (read > 0) {99totalRead += read;100}101if (read < num) {102break;103}104}105106if (result == 0) {107int error = GetLastError();108if (error == ERROR_BROKEN_PIPE) {109return IOS_EOF;110}111if (error == ERROR_NO_DATA) {112return IOS_UNAVAILABLE;113}114JNU_ThrowIOExceptionWithLastError(env, "Read failed");115return IOS_THROWN;116}117118return convertLongReturnVal(env, totalRead, JNI_TRUE);119}120121JNIEXPORT jint JNICALL122Java_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo,123jlong address, jint len, jlong offset)124{125DWORD read = 0;126BOOL result = 0;127HANDLE h = (HANDLE)(handleval(env, fdo));128LARGE_INTEGER currPos;129OVERLAPPED ov;130131if (h == INVALID_HANDLE_VALUE) {132JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");133return IOS_THROWN;134}135136currPos.QuadPart = 0;137result = SetFilePointerEx(h, currPos, &currPos, FILE_CURRENT);138if (result == 0) {139JNU_ThrowIOExceptionWithLastError(env, "Seek failed");140return IOS_THROWN;141}142143ZeroMemory(&ov, sizeof(ov));144ov.Offset = (DWORD)offset;145ov.OffsetHigh = (DWORD)(offset >> 32);146147result = ReadFile(h, /* File handle to read */148(LPVOID)address, /* address to put data */149len, /* number of bytes to read */150&read, /* number of bytes read */151&ov); /* position to read from */152153if (result == 0) {154int error = GetLastError();155if (error == ERROR_BROKEN_PIPE) {156return IOS_EOF;157}158if (error == ERROR_NO_DATA) {159return IOS_UNAVAILABLE;160}161if (error != ERROR_HANDLE_EOF) {162JNU_ThrowIOExceptionWithLastError(env, "Read failed");163return IOS_THROWN;164}165}166167result = SetFilePointerEx(h, currPos, NULL, FILE_BEGIN);168if (result == 0) {169JNU_ThrowIOExceptionWithLastError(env, "Seek failed");170return IOS_THROWN;171}172173return convertReturnVal(env, (jint)read, JNI_TRUE);174}175176JNIEXPORT jint JNICALL177Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz, jobject fdo,178jlong address, jint len, jboolean append)179{180BOOL result = 0;181DWORD written = 0;182HANDLE h = (HANDLE)(handleval(env, fdo));183184if (h != INVALID_HANDLE_VALUE) {185OVERLAPPED ov;186LPOVERLAPPED lpOv;187if (append == JNI_TRUE) {188ZeroMemory(&ov, sizeof(ov));189ov.Offset = (DWORD)0xFFFFFFFF;190ov.OffsetHigh = (DWORD)0xFFFFFFFF;191lpOv = &ov;192} else {193lpOv = NULL;194}195result = WriteFile(h, /* File handle to write */196(LPCVOID)address, /* pointer to the buffer */197len, /* number of bytes to write */198&written, /* receives number of bytes written */199lpOv); /* overlapped struct */200}201202if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {203JNU_ThrowIOExceptionWithLastError(env, "Write failed");204return IOS_THROWN;205}206207return convertReturnVal(env, (jint)written, JNI_FALSE);208}209210JNIEXPORT jlong JNICALL211Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz, jobject fdo,212jlong address, jint len, jboolean append)213{214BOOL result = 0;215DWORD written = 0;216HANDLE h = (HANDLE)(handleval(env, fdo));217jlong totalWritten = 0;218219if (h != INVALID_HANDLE_VALUE) {220LPVOID loc;221int i = 0;222DWORD num = 0;223struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);224OVERLAPPED ov;225LPOVERLAPPED lpOv;226if (append == JNI_TRUE) {227ZeroMemory(&ov, sizeof(ov));228ov.Offset = (DWORD)0xFFFFFFFF;229ov.OffsetHigh = (DWORD)0xFFFFFFFF;230lpOv = &ov;231} else {232lpOv = NULL;233}234for(i=0; i<len; i++) {235loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);236num = iovecp[i].iov_len;237result = WriteFile(h, /* File handle to write */238loc, /* pointers to the buffers */239num, /* number of bytes to write */240&written,/* receives number of bytes written */241lpOv); /* overlapped struct */242if (written > 0) {243totalWritten += written;244}245if (written < num) {246break;247}248}249}250251if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {252JNU_ThrowIOExceptionWithLastError(env, "Write failed");253return IOS_THROWN;254}255256return convertLongReturnVal(env, totalWritten, JNI_FALSE);257}258259JNIEXPORT jint JNICALL260Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,261jlong address, jint len, jlong offset)262{263BOOL result = 0;264DWORD written = 0;265HANDLE h = (HANDLE)(handleval(env, fdo));266LARGE_INTEGER currPos;267OVERLAPPED ov;268269currPos.QuadPart = 0;270result = SetFilePointerEx(h, currPos, &currPos, FILE_CURRENT);271if (result == 0) {272JNU_ThrowIOExceptionWithLastError(env, "Seek failed");273return IOS_THROWN;274}275276ZeroMemory(&ov, sizeof(ov));277ov.Offset = (DWORD)offset;278ov.OffsetHigh = (DWORD)(offset >> 32);279280result = WriteFile(h, /* File handle to write */281(LPCVOID)address, /* pointer to the buffer */282len, /* number of bytes to write */283&written, /* receives number of bytes written */284&ov); /* position to write at */285286if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {287JNU_ThrowIOExceptionWithLastError(env, "Write failed");288return IOS_THROWN;289}290291result = SetFilePointerEx(h, currPos, NULL, FILE_BEGIN);292if (result == 0) {293JNU_ThrowIOExceptionWithLastError(env, "Seek failed");294return IOS_THROWN;295}296297return convertReturnVal(env, (jint)written, JNI_FALSE);298}299300JNIEXPORT jlong JNICALL301Java_sun_nio_ch_FileDispatcherImpl_seek0(JNIEnv *env, jclass clazz,302jobject fdo, jlong offset)303{304BOOL result = 0;305HANDLE h = (HANDLE)(handleval(env, fdo));306LARGE_INTEGER where;307DWORD whence;308309if (offset < 0) {310where.QuadPart = 0;311whence = FILE_CURRENT;312} else {313where.QuadPart = offset;314whence = FILE_BEGIN;315}316317result = SetFilePointerEx(h, where, &where, whence);318if (result == 0) {319JNU_ThrowIOExceptionWithLastError(env, "SetFilePointerEx failed");320return IOS_THROWN;321}322return (jlong)where.QuadPart;323}324325JNIEXPORT jint JNICALL326Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,327jobject fdo, jboolean md)328{329int result = 0;330HANDLE h = (HANDLE)(handleval(env, fdo));331332if (h != INVALID_HANDLE_VALUE) {333result = FlushFileBuffers(h);334if (result == 0) {335int error = GetLastError();336if (error != ERROR_ACCESS_DENIED) {337JNU_ThrowIOExceptionWithLastError(env, "Force failed");338return IOS_THROWN;339}340}341} else {342JNU_ThrowIOExceptionWithLastError(env, "Force failed");343return IOS_THROWN;344}345return 0;346}347348JNIEXPORT jint JNICALL349Java_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,350jobject fdo, jlong size)351{352BOOL result = 0;353HANDLE h = (HANDLE)(handleval(env, fdo));354FILE_END_OF_FILE_INFO eofInfo;355356eofInfo.EndOfFile.QuadPart = size;357result = SetFileInformationByHandle(h,358FileEndOfFileInfo,359&eofInfo,360sizeof(eofInfo));361if (result == 0) {362JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");363return IOS_THROWN;364}365return 0;366}367368JNIEXPORT jlong JNICALL369Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)370{371BOOL result = 0;372HANDLE h = (HANDLE)(handleval(env, fdo));373LARGE_INTEGER size;374375result = GetFileSizeEx(h, &size);376if (result == 0) {377JNU_ThrowIOExceptionWithLastError(env, "Size failed");378return IOS_THROWN;379}380return (jlong)size.QuadPart;381}382383JNIEXPORT jint JNICALL384Java_sun_nio_ch_FileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,385jboolean block, jlong pos, jlong size,386jboolean shared)387{388HANDLE h = (HANDLE)(handleval(env, fdo));389DWORD lowPos = (DWORD)pos;390long highPos = (long)(pos >> 32);391DWORD lowNumBytes = (DWORD)size;392DWORD highNumBytes = (DWORD)(size >> 32);393BOOL result;394DWORD flags = 0;395OVERLAPPED o;396o.hEvent = 0;397o.Offset = lowPos;398o.OffsetHigh = highPos;399if (block == JNI_FALSE) {400flags |= LOCKFILE_FAIL_IMMEDIATELY;401}402if (shared == JNI_FALSE) {403flags |= LOCKFILE_EXCLUSIVE_LOCK;404}405result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o);406if (result == 0) {407int error = GetLastError();408if (error == ERROR_IO_PENDING) {409DWORD dwBytes;410result = GetOverlappedResult(h, &o, &dwBytes, TRUE);411if (result != 0) {412return sun_nio_ch_FileDispatcherImpl_LOCKED;413}414error = GetLastError();415}416if (error != ERROR_LOCK_VIOLATION) {417JNU_ThrowIOExceptionWithLastError(env, "Lock failed");418return sun_nio_ch_FileDispatcherImpl_NO_LOCK;419}420if (flags & LOCKFILE_FAIL_IMMEDIATELY) {421return sun_nio_ch_FileDispatcherImpl_NO_LOCK;422}423JNU_ThrowIOExceptionWithLastError(env, "Lock failed");424return sun_nio_ch_FileDispatcherImpl_NO_LOCK;425}426return sun_nio_ch_FileDispatcherImpl_LOCKED;427}428429JNIEXPORT void JNICALL430Java_sun_nio_ch_FileDispatcherImpl_release0(JNIEnv *env, jobject this,431jobject fdo, jlong pos, jlong size)432{433HANDLE h = (HANDLE)(handleval(env, fdo));434DWORD lowPos = (DWORD)pos;435long highPos = (long)(pos >> 32);436DWORD lowNumBytes = (DWORD)size;437DWORD highNumBytes = (DWORD)(size >> 32);438BOOL result = 0;439OVERLAPPED o;440o.hEvent = 0;441o.Offset = lowPos;442o.OffsetHigh = highPos;443result = UnlockFileEx(h, 0, lowNumBytes, highNumBytes, &o);444if (result == 0) {445int error = GetLastError();446if (error == ERROR_IO_PENDING) {447DWORD dwBytes;448result = GetOverlappedResult(h, &o, &dwBytes, TRUE);449if (result != 0) {450return;451}452error = GetLastError();453}454if (error != ERROR_NOT_LOCKED) {455JNU_ThrowIOExceptionWithLastError(env, "Release failed");456}457}458}459460JNIEXPORT void JNICALL461Java_sun_nio_ch_FileDispatcherImpl_close0(JNIEnv *env, jclass clazz, jobject fdo)462{463HANDLE h = (HANDLE)handleval(env, fdo);464if (h != INVALID_HANDLE_VALUE) {465int result = CloseHandle(h);466if (result == 0)467JNU_ThrowIOExceptionWithLastError(env, "Close failed");468}469}470471JNIEXPORT jlong JNICALL472Java_sun_nio_ch_FileDispatcherImpl_duplicateHandle(JNIEnv *env, jclass this, jlong handle)473{474HANDLE hProcess = GetCurrentProcess();475HANDLE hFile = jlong_to_ptr(handle);476HANDLE hResult;477BOOL res = DuplicateHandle(hProcess, hFile, hProcess, &hResult, 0, FALSE,478DUPLICATE_SAME_ACCESS);479if (res == 0)480JNU_ThrowIOExceptionWithLastError(env, "DuplicateHandle failed");481return ptr_to_jlong(hResult);482}483484JNIEXPORT jint JNICALL485Java_sun_nio_ch_FileDispatcherImpl_setDirect0(JNIEnv *env, jclass this,486jobject fdObj, jobject buffer)487{488jint result = -1;489490HANDLE orig = (HANDLE)(handleval(env, fdObj));491492HANDLE modify = ReOpenFile(orig, 0, 0,493FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH);494495if (modify != INVALID_HANDLE_VALUE) {496DWORD sectorsPerCluster;497DWORD bytesPerSector;498DWORD numberOfFreeClusters;499DWORD totalNumberOfClusters;500LPCWSTR lpRootPathName = (*env)->GetDirectBufferAddress(env, buffer);501BOOL res = GetDiskFreeSpaceW(lpRootPathName,502§orsPerCluster,503&bytesPerSector,504&numberOfFreeClusters,505&totalNumberOfClusters);506if (res == 0) {507JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");508}509result = bytesPerSector;510}511return result;512}513514515