Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c
41134 views
1
/*
2
* Copyright (c) 2000, 2018, 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
23
* questions.
24
*/
25
26
#include <windows.h>
27
#include "jni.h"
28
#include "jni_util.h"
29
#include "jvm.h"
30
#include "jlong.h"
31
#include "sun_nio_ch_FileDispatcherImpl.h"
32
#include <io.h>
33
#include "nio.h"
34
#include "nio_util.h"
35
#include "jlong.h"
36
37
38
/**************************************************************
39
* FileDispatcherImpl.c
40
*/
41
42
JNIEXPORT jint JNICALL
43
Java_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz, jobject fdo,
44
jlong address, jint len)
45
{
46
DWORD read = 0;
47
BOOL result = 0;
48
HANDLE h = (HANDLE)(handleval(env, fdo));
49
50
if (h == INVALID_HANDLE_VALUE) {
51
JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");
52
return IOS_THROWN;
53
}
54
result = ReadFile(h, /* File handle to read */
55
(LPVOID)address, /* address to put data */
56
len, /* number of bytes to read */
57
&read, /* number of bytes read */
58
NULL); /* no overlapped struct */
59
if (result == 0) {
60
int error = GetLastError();
61
if (error == ERROR_BROKEN_PIPE) {
62
return IOS_EOF;
63
}
64
if (error == ERROR_NO_DATA) {
65
return IOS_UNAVAILABLE;
66
}
67
JNU_ThrowIOExceptionWithLastError(env, "Read failed");
68
return IOS_THROWN;
69
}
70
return convertReturnVal(env, (jint)read, JNI_TRUE);
71
}
72
73
JNIEXPORT jlong JNICALL
74
Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz, jobject fdo,
75
jlong address, jint len)
76
{
77
DWORD read = 0;
78
BOOL result = 0;
79
jlong totalRead = 0;
80
LPVOID loc;
81
int i = 0;
82
DWORD num = 0;
83
struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);
84
HANDLE h = (HANDLE)(handleval(env, fdo));
85
86
if (h == INVALID_HANDLE_VALUE) {
87
JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");
88
return IOS_THROWN;
89
}
90
91
for(i=0; i<len; i++) {
92
loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);
93
num = iovecp[i].iov_len;
94
result = ReadFile(h, /* File handle to read */
95
loc, /* address to put data */
96
num, /* number of bytes to read */
97
&read, /* number of bytes read */
98
NULL); /* no overlapped struct */
99
if (read > 0) {
100
totalRead += read;
101
}
102
if (read < num) {
103
break;
104
}
105
}
106
107
if (result == 0) {
108
int error = GetLastError();
109
if (error == ERROR_BROKEN_PIPE) {
110
return IOS_EOF;
111
}
112
if (error == ERROR_NO_DATA) {
113
return IOS_UNAVAILABLE;
114
}
115
JNU_ThrowIOExceptionWithLastError(env, "Read failed");
116
return IOS_THROWN;
117
}
118
119
return convertLongReturnVal(env, totalRead, JNI_TRUE);
120
}
121
122
JNIEXPORT jint JNICALL
123
Java_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo,
124
jlong address, jint len, jlong offset)
125
{
126
DWORD read = 0;
127
BOOL result = 0;
128
HANDLE h = (HANDLE)(handleval(env, fdo));
129
LARGE_INTEGER currPos;
130
OVERLAPPED ov;
131
132
if (h == INVALID_HANDLE_VALUE) {
133
JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");
134
return IOS_THROWN;
135
}
136
137
currPos.QuadPart = 0;
138
result = SetFilePointerEx(h, currPos, &currPos, FILE_CURRENT);
139
if (result == 0) {
140
JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
141
return IOS_THROWN;
142
}
143
144
ZeroMemory(&ov, sizeof(ov));
145
ov.Offset = (DWORD)offset;
146
ov.OffsetHigh = (DWORD)(offset >> 32);
147
148
result = ReadFile(h, /* File handle to read */
149
(LPVOID)address, /* address to put data */
150
len, /* number of bytes to read */
151
&read, /* number of bytes read */
152
&ov); /* position to read from */
153
154
if (result == 0) {
155
int error = GetLastError();
156
if (error == ERROR_BROKEN_PIPE) {
157
return IOS_EOF;
158
}
159
if (error == ERROR_NO_DATA) {
160
return IOS_UNAVAILABLE;
161
}
162
if (error != ERROR_HANDLE_EOF) {
163
JNU_ThrowIOExceptionWithLastError(env, "Read failed");
164
return IOS_THROWN;
165
}
166
}
167
168
result = SetFilePointerEx(h, currPos, NULL, FILE_BEGIN);
169
if (result == 0) {
170
JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
171
return IOS_THROWN;
172
}
173
174
return convertReturnVal(env, (jint)read, JNI_TRUE);
175
}
176
177
JNIEXPORT jint JNICALL
178
Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz, jobject fdo,
179
jlong address, jint len, jboolean append)
180
{
181
BOOL result = 0;
182
DWORD written = 0;
183
HANDLE h = (HANDLE)(handleval(env, fdo));
184
185
if (h != INVALID_HANDLE_VALUE) {
186
OVERLAPPED ov;
187
LPOVERLAPPED lpOv;
188
if (append == JNI_TRUE) {
189
ZeroMemory(&ov, sizeof(ov));
190
ov.Offset = (DWORD)0xFFFFFFFF;
191
ov.OffsetHigh = (DWORD)0xFFFFFFFF;
192
lpOv = &ov;
193
} else {
194
lpOv = NULL;
195
}
196
result = WriteFile(h, /* File handle to write */
197
(LPCVOID)address, /* pointer to the buffer */
198
len, /* number of bytes to write */
199
&written, /* receives number of bytes written */
200
lpOv); /* overlapped struct */
201
}
202
203
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
204
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
205
return IOS_THROWN;
206
}
207
208
return convertReturnVal(env, (jint)written, JNI_FALSE);
209
}
210
211
JNIEXPORT jlong JNICALL
212
Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz, jobject fdo,
213
jlong address, jint len, jboolean append)
214
{
215
BOOL result = 0;
216
DWORD written = 0;
217
HANDLE h = (HANDLE)(handleval(env, fdo));
218
jlong totalWritten = 0;
219
220
if (h != INVALID_HANDLE_VALUE) {
221
LPVOID loc;
222
int i = 0;
223
DWORD num = 0;
224
struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);
225
OVERLAPPED ov;
226
LPOVERLAPPED lpOv;
227
if (append == JNI_TRUE) {
228
ZeroMemory(&ov, sizeof(ov));
229
ov.Offset = (DWORD)0xFFFFFFFF;
230
ov.OffsetHigh = (DWORD)0xFFFFFFFF;
231
lpOv = &ov;
232
} else {
233
lpOv = NULL;
234
}
235
for(i=0; i<len; i++) {
236
loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);
237
num = iovecp[i].iov_len;
238
result = WriteFile(h, /* File handle to write */
239
loc, /* pointers to the buffers */
240
num, /* number of bytes to write */
241
&written,/* receives number of bytes written */
242
lpOv); /* overlapped struct */
243
if (written > 0) {
244
totalWritten += written;
245
}
246
if (written < num) {
247
break;
248
}
249
}
250
}
251
252
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
253
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
254
return IOS_THROWN;
255
}
256
257
return convertLongReturnVal(env, totalWritten, JNI_FALSE);
258
}
259
260
JNIEXPORT jint JNICALL
261
Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,
262
jlong address, jint len, jlong offset)
263
{
264
BOOL result = 0;
265
DWORD written = 0;
266
HANDLE h = (HANDLE)(handleval(env, fdo));
267
LARGE_INTEGER currPos;
268
OVERLAPPED ov;
269
270
currPos.QuadPart = 0;
271
result = SetFilePointerEx(h, currPos, &currPos, FILE_CURRENT);
272
if (result == 0) {
273
JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
274
return IOS_THROWN;
275
}
276
277
ZeroMemory(&ov, sizeof(ov));
278
ov.Offset = (DWORD)offset;
279
ov.OffsetHigh = (DWORD)(offset >> 32);
280
281
result = WriteFile(h, /* File handle to write */
282
(LPCVOID)address, /* pointer to the buffer */
283
len, /* number of bytes to write */
284
&written, /* receives number of bytes written */
285
&ov); /* position to write at */
286
287
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
288
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
289
return IOS_THROWN;
290
}
291
292
result = SetFilePointerEx(h, currPos, NULL, FILE_BEGIN);
293
if (result == 0) {
294
JNU_ThrowIOExceptionWithLastError(env, "Seek failed");
295
return IOS_THROWN;
296
}
297
298
return convertReturnVal(env, (jint)written, JNI_FALSE);
299
}
300
301
JNIEXPORT jlong JNICALL
302
Java_sun_nio_ch_FileDispatcherImpl_seek0(JNIEnv *env, jclass clazz,
303
jobject fdo, jlong offset)
304
{
305
BOOL result = 0;
306
HANDLE h = (HANDLE)(handleval(env, fdo));
307
LARGE_INTEGER where;
308
DWORD whence;
309
310
if (offset < 0) {
311
where.QuadPart = 0;
312
whence = FILE_CURRENT;
313
} else {
314
where.QuadPart = offset;
315
whence = FILE_BEGIN;
316
}
317
318
result = SetFilePointerEx(h, where, &where, whence);
319
if (result == 0) {
320
JNU_ThrowIOExceptionWithLastError(env, "SetFilePointerEx failed");
321
return IOS_THROWN;
322
}
323
return (jlong)where.QuadPart;
324
}
325
326
JNIEXPORT jint JNICALL
327
Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
328
jobject fdo, jboolean md)
329
{
330
int result = 0;
331
HANDLE h = (HANDLE)(handleval(env, fdo));
332
333
if (h != INVALID_HANDLE_VALUE) {
334
result = FlushFileBuffers(h);
335
if (result == 0) {
336
int error = GetLastError();
337
if (error != ERROR_ACCESS_DENIED) {
338
JNU_ThrowIOExceptionWithLastError(env, "Force failed");
339
return IOS_THROWN;
340
}
341
}
342
} else {
343
JNU_ThrowIOExceptionWithLastError(env, "Force failed");
344
return IOS_THROWN;
345
}
346
return 0;
347
}
348
349
JNIEXPORT jint JNICALL
350
Java_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,
351
jobject fdo, jlong size)
352
{
353
BOOL result = 0;
354
HANDLE h = (HANDLE)(handleval(env, fdo));
355
FILE_END_OF_FILE_INFO eofInfo;
356
357
eofInfo.EndOfFile.QuadPart = size;
358
result = SetFileInformationByHandle(h,
359
FileEndOfFileInfo,
360
&eofInfo,
361
sizeof(eofInfo));
362
if (result == 0) {
363
JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");
364
return IOS_THROWN;
365
}
366
return 0;
367
}
368
369
JNIEXPORT jlong JNICALL
370
Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
371
{
372
BOOL result = 0;
373
HANDLE h = (HANDLE)(handleval(env, fdo));
374
LARGE_INTEGER size;
375
376
result = GetFileSizeEx(h, &size);
377
if (result == 0) {
378
JNU_ThrowIOExceptionWithLastError(env, "Size failed");
379
return IOS_THROWN;
380
}
381
return (jlong)size.QuadPart;
382
}
383
384
JNIEXPORT jint JNICALL
385
Java_sun_nio_ch_FileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
386
jboolean block, jlong pos, jlong size,
387
jboolean shared)
388
{
389
HANDLE h = (HANDLE)(handleval(env, fdo));
390
DWORD lowPos = (DWORD)pos;
391
long highPos = (long)(pos >> 32);
392
DWORD lowNumBytes = (DWORD)size;
393
DWORD highNumBytes = (DWORD)(size >> 32);
394
BOOL result;
395
DWORD flags = 0;
396
OVERLAPPED o;
397
o.hEvent = 0;
398
o.Offset = lowPos;
399
o.OffsetHigh = highPos;
400
if (block == JNI_FALSE) {
401
flags |= LOCKFILE_FAIL_IMMEDIATELY;
402
}
403
if (shared == JNI_FALSE) {
404
flags |= LOCKFILE_EXCLUSIVE_LOCK;
405
}
406
result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o);
407
if (result == 0) {
408
int error = GetLastError();
409
if (error == ERROR_IO_PENDING) {
410
DWORD dwBytes;
411
result = GetOverlappedResult(h, &o, &dwBytes, TRUE);
412
if (result != 0) {
413
return sun_nio_ch_FileDispatcherImpl_LOCKED;
414
}
415
error = GetLastError();
416
}
417
if (error != ERROR_LOCK_VIOLATION) {
418
JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
419
return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
420
}
421
if (flags & LOCKFILE_FAIL_IMMEDIATELY) {
422
return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
423
}
424
JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
425
return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
426
}
427
return sun_nio_ch_FileDispatcherImpl_LOCKED;
428
}
429
430
JNIEXPORT void JNICALL
431
Java_sun_nio_ch_FileDispatcherImpl_release0(JNIEnv *env, jobject this,
432
jobject fdo, jlong pos, jlong size)
433
{
434
HANDLE h = (HANDLE)(handleval(env, fdo));
435
DWORD lowPos = (DWORD)pos;
436
long highPos = (long)(pos >> 32);
437
DWORD lowNumBytes = (DWORD)size;
438
DWORD highNumBytes = (DWORD)(size >> 32);
439
BOOL result = 0;
440
OVERLAPPED o;
441
o.hEvent = 0;
442
o.Offset = lowPos;
443
o.OffsetHigh = highPos;
444
result = UnlockFileEx(h, 0, lowNumBytes, highNumBytes, &o);
445
if (result == 0) {
446
int error = GetLastError();
447
if (error == ERROR_IO_PENDING) {
448
DWORD dwBytes;
449
result = GetOverlappedResult(h, &o, &dwBytes, TRUE);
450
if (result != 0) {
451
return;
452
}
453
error = GetLastError();
454
}
455
if (error != ERROR_NOT_LOCKED) {
456
JNU_ThrowIOExceptionWithLastError(env, "Release failed");
457
}
458
}
459
}
460
461
JNIEXPORT void JNICALL
462
Java_sun_nio_ch_FileDispatcherImpl_close0(JNIEnv *env, jclass clazz, jobject fdo)
463
{
464
HANDLE h = (HANDLE)handleval(env, fdo);
465
if (h != INVALID_HANDLE_VALUE) {
466
int result = CloseHandle(h);
467
if (result == 0)
468
JNU_ThrowIOExceptionWithLastError(env, "Close failed");
469
}
470
}
471
472
JNIEXPORT jlong JNICALL
473
Java_sun_nio_ch_FileDispatcherImpl_duplicateHandle(JNIEnv *env, jclass this, jlong handle)
474
{
475
HANDLE hProcess = GetCurrentProcess();
476
HANDLE hFile = jlong_to_ptr(handle);
477
HANDLE hResult;
478
BOOL res = DuplicateHandle(hProcess, hFile, hProcess, &hResult, 0, FALSE,
479
DUPLICATE_SAME_ACCESS);
480
if (res == 0)
481
JNU_ThrowIOExceptionWithLastError(env, "DuplicateHandle failed");
482
return ptr_to_jlong(hResult);
483
}
484
485
JNIEXPORT jint JNICALL
486
Java_sun_nio_ch_FileDispatcherImpl_setDirect0(JNIEnv *env, jclass this,
487
jobject fdObj, jobject buffer)
488
{
489
jint result = -1;
490
491
HANDLE orig = (HANDLE)(handleval(env, fdObj));
492
493
HANDLE modify = ReOpenFile(orig, 0, 0,
494
FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH);
495
496
if (modify != INVALID_HANDLE_VALUE) {
497
DWORD sectorsPerCluster;
498
DWORD bytesPerSector;
499
DWORD numberOfFreeClusters;
500
DWORD totalNumberOfClusters;
501
LPCWSTR lpRootPathName = (*env)->GetDirectBufferAddress(env, buffer);
502
BOOL res = GetDiskFreeSpaceW(lpRootPathName,
503
&sectorsPerCluster,
504
&bytesPerSector,
505
&numberOfFreeClusters,
506
&totalNumberOfClusters);
507
if (res == 0) {
508
JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");
509
}
510
result = bytesPerSector;
511
}
512
return result;
513
}
514
515