Direct encrypted files read/write & More compliant EncryptedVolumeDataSource
This commit is contained in:
parent
8f5afca823
commit
7cdfc32c31
@ -1 +1 @@
|
|||||||
Subproject commit c0600c262480f6fb3d31e2b500ba04714f1ff342
|
Subproject commit dc82772e5eb8063bace8415193eebc52cedcec64
|
@ -459,7 +459,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
videoCapture?.startRecording(VideoCapture.OutputFileOptions(object : SeekableWriter {
|
videoCapture?.startRecording(VideoCapture.OutputFileOptions(object : SeekableWriter {
|
||||||
var offset = 0L
|
var offset = 0L
|
||||||
override fun write(byteArray: ByteArray) {
|
override fun write(byteArray: ByteArray) {
|
||||||
offset += encryptedVolume.write(fileHandle, offset, byteArray, byteArray.size)
|
offset += encryptedVolume.write(fileHandle, offset, byteArray, 0, byteArray.size.toLong())
|
||||||
}
|
}
|
||||||
override fun seek(offset: Long) {
|
override fun seek(offset: Long) {
|
||||||
this.offset = offset
|
this.offset = offset
|
||||||
|
@ -9,7 +9,6 @@ object ConstValues {
|
|||||||
const val CRYFS_LOCAL_STATE_DIR = "cryfsLocalState"
|
const val CRYFS_LOCAL_STATE_DIR = "cryfsLocalState"
|
||||||
const val SORT_ORDER_KEY = "sort_order"
|
const val SORT_ORDER_KEY = "sort_order"
|
||||||
val FAKE_URI: Uri = Uri.parse("fakeuri://droidfs")
|
val FAKE_URI: Uri = Uri.parse("fakeuri://droidfs")
|
||||||
const val MAX_KERNEL_WRITE = 128*1024
|
|
||||||
const val WIPE_PASSES = 2
|
const val WIPE_PASSES = 2
|
||||||
const val IO_BUFF_SIZE = 16384
|
const val IO_BUFF_SIZE = 16384
|
||||||
const val SLIDESHOW_DELAY: Long = 4000
|
const val SLIDESHOW_DELAY: Long = 4000
|
||||||
|
@ -131,10 +131,10 @@ class FileOperationService : Service() {
|
|||||||
if (dstFileHandle != -1L) {
|
if (dstFileHandle != -1L) {
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE)
|
val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE)
|
||||||
var length: Int
|
var length: Long
|
||||||
while (remoteEncryptedVolume.read(srcFileHandle, ioBuffer, offset).also { length = it } > 0) {
|
while (remoteEncryptedVolume.read(srcFileHandle, offset, ioBuffer, 0, ioBuffer.size.toLong()).also { length = it.toLong() } > 0) {
|
||||||
val written = encryptedVolume.write(dstFileHandle, offset, ioBuffer, length).toLong()
|
val written = encryptedVolume.write(dstFileHandle, offset, ioBuffer, 0, length).toLong()
|
||||||
if (written == length.toLong()) {
|
if (written == length) {
|
||||||
offset += written
|
offset += written
|
||||||
} else {
|
} else {
|
||||||
success = false
|
success = false
|
||||||
|
@ -1,23 +1,29 @@
|
|||||||
package sushi.hardcore.droidfs.file_viewers
|
package sushi.hardcore.droidfs.file_viewers
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import com.google.android.exoplayer2.C
|
||||||
import com.google.android.exoplayer2.upstream.DataSource
|
import com.google.android.exoplayer2.upstream.DataSource
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec
|
import com.google.android.exoplayer2.upstream.DataSpec
|
||||||
import com.google.android.exoplayer2.upstream.TransferListener
|
import com.google.android.exoplayer2.upstream.TransferListener
|
||||||
import sushi.hardcore.droidfs.ConstValues
|
import sushi.hardcore.droidfs.ConstValues
|
||||||
import sushi.hardcore.droidfs.filesystems.EncryptedVolume
|
import sushi.hardcore.droidfs.filesystems.EncryptedVolume
|
||||||
import kotlin.math.ceil
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class EncryptedVolumeDataSource(private val encryptedVolume: EncryptedVolume, private val filePath: String): DataSource {
|
class EncryptedVolumeDataSource(private val encryptedVolume: EncryptedVolume, private val filePath: String): DataSource {
|
||||||
private var fileHandle = -1L
|
private var fileHandle = -1L
|
||||||
private var fileSize: Long = -1
|
|
||||||
private var fileOffset: Long = 0
|
private var fileOffset: Long = 0
|
||||||
|
private var bytesRemaining: Long = -1
|
||||||
|
|
||||||
override fun open(dataSpec: DataSpec): Long {
|
override fun open(dataSpec: DataSpec): Long {
|
||||||
fileOffset = dataSpec.position
|
|
||||||
fileHandle = encryptedVolume.openFile(filePath)
|
fileHandle = encryptedVolume.openFile(filePath)
|
||||||
fileSize = encryptedVolume.getAttr(filePath)!!.size
|
fileOffset = dataSpec.position
|
||||||
return fileSize
|
val fileSize = encryptedVolume.getAttr(filePath)!!.size
|
||||||
|
bytesRemaining = if (dataSpec.length == C.LENGTH_UNSET.toLong()) {
|
||||||
|
fileSize - fileOffset
|
||||||
|
} else {
|
||||||
|
min(fileSize, dataSpec.length)
|
||||||
|
}
|
||||||
|
return bytesRemaining
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUri(): Uri {
|
override fun getUri(): Uri {
|
||||||
@ -33,23 +39,18 @@ class EncryptedVolumeDataSource(private val encryptedVolume: EncryptedVolume, pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun read(buffer: ByteArray, offset: Int, readLength: Int): Int {
|
override fun read(buffer: ByteArray, offset: Int, readLength: Int): Int {
|
||||||
if (fileOffset >= fileSize){
|
val originalOffset = fileOffset
|
||||||
return -1
|
while (fileOffset < originalOffset+readLength && encryptedVolume.read(
|
||||||
}
|
fileHandle,
|
||||||
var totalRead = 0
|
fileOffset,
|
||||||
for (i in 0 until ceil(readLength.toDouble()/ConstValues.MAX_KERNEL_WRITE).toInt()){
|
buffer,
|
||||||
val tmpReadLength = min(readLength-totalRead, ConstValues.MAX_KERNEL_WRITE)
|
offset+(fileOffset-originalOffset),
|
||||||
val tmpBuff = if (fileOffset+tmpReadLength > fileSize){
|
(originalOffset+readLength)-fileOffset
|
||||||
ByteArray((fileSize-fileOffset).toInt())
|
).also { fileOffset += it } > 0
|
||||||
} else {
|
) {}
|
||||||
ByteArray(tmpReadLength)
|
val totalRead = fileOffset-originalOffset
|
||||||
}
|
bytesRemaining -= totalRead
|
||||||
val read = encryptedVolume.read(fileHandle, tmpBuff, fileOffset)
|
return totalRead.toInt()
|
||||||
System.arraycopy(tmpBuff, 0, buffer, offset+totalRead, read)
|
|
||||||
fileOffset += read
|
|
||||||
totalRead += read
|
|
||||||
}
|
|
||||||
return totalRead
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Factory(private val encryptedVolume: EncryptedVolume, private val filePath: String): DataSource.Factory {
|
class Factory(private val encryptedVolume: EncryptedVolume, private val filePath: String): DataSource.Factory {
|
||||||
|
@ -70,23 +70,12 @@ class TextEditor: FileViewerActivity() {
|
|||||||
val content = editor.text.toString().toByteArray()
|
val content = editor.text.toString().toByteArray()
|
||||||
val fileHandle = encryptedVolume.openFile(filePath)
|
val fileHandle = encryptedVolume.openFile(filePath)
|
||||||
if (fileHandle != -1L) {
|
if (fileHandle != -1L) {
|
||||||
val buff = ByteArrayInputStream(content)
|
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE)
|
while (offset < content.size && encryptedVolume.write(fileHandle, offset, content, offset, content.size.toLong()).also { offset += it } > 0) {}
|
||||||
var length: Int
|
|
||||||
while (buff.read(ioBuffer).also { length = it } > 0) {
|
|
||||||
val written = encryptedVolume.write(fileHandle, offset, ioBuffer, length).toLong()
|
|
||||||
if (written == length.toLong()) {
|
|
||||||
offset += written
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (offset == content.size.toLong()){
|
if (offset == content.size.toLong()){
|
||||||
success = encryptedVolume.truncate(filePath, offset)
|
success = encryptedVolume.truncate(filePath, offset)
|
||||||
}
|
}
|
||||||
encryptedVolume.closeFile(fileHandle)
|
encryptedVolume.closeFile(fileHandle)
|
||||||
buff.close()
|
|
||||||
}
|
}
|
||||||
if (success){
|
if (success){
|
||||||
Toast.makeText(this, getString(R.string.file_saved), Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, getString(R.string.file_saved), Toast.LENGTH_SHORT).show()
|
||||||
|
@ -33,8 +33,8 @@ class CryfsVolume(private val fusePtr: Long): EncryptedVolume() {
|
|||||||
): Boolean
|
): Boolean
|
||||||
private external fun nativeCreate(fusePtr: Long, path: String, mode: Int): Long
|
private external fun nativeCreate(fusePtr: Long, path: String, mode: Int): Long
|
||||||
private external fun nativeOpen(fusePtr: Long, path: String, flags: Int): Long
|
private external fun nativeOpen(fusePtr: Long, path: String, flags: Int): Long
|
||||||
private external fun nativeRead(fusePtr: Long, fileHandle: Long, buffer: ByteArray, offset: Long): Int
|
private external fun nativeRead(fusePtr: Long, fileHandle: Long, fileOffset: Long, buffer: ByteArray, dstOffset: Long, length: Long): Int
|
||||||
private external fun nativeWrite(fusePtr: Long, fileHandle: Long, offset: Long, buffer: ByteArray, size: Int): Int
|
private external fun nativeWrite(fusePtr: Long, fileHandle: Long, fileOffset: Long, buffer: ByteArray, srcOffset: Long, length: Long): Int
|
||||||
private external fun nativeTruncate(fusePtr: Long, path: String, size: Long): Boolean
|
private external fun nativeTruncate(fusePtr: Long, path: String, size: Long): Boolean
|
||||||
private external fun nativeDeleteFile(fusePtr: Long, path: String): Boolean
|
private external fun nativeDeleteFile(fusePtr: Long, path: String): Boolean
|
||||||
private external fun nativeCloseFile(fusePtr: Long, fileHandle: Long): Boolean
|
private external fun nativeCloseFile(fusePtr: Long, fileHandle: Long): Boolean
|
||||||
@ -101,12 +101,12 @@ class CryfsVolume(private val fusePtr: Long): EncryptedVolume() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(fileHandle: Long, buffer: ByteArray, offset: Long): Int {
|
override fun read(fileHandle: Long, fileOffset: Long, buffer: ByteArray, dstOffset: Long, length: Long): Int {
|
||||||
return nativeRead(fusePtr, fileHandle, buffer, offset)
|
return nativeRead(fusePtr, fileHandle, fileOffset, buffer, dstOffset, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun write(fileHandle: Long, offset: Long, buffer: ByteArray, size: Int): Int {
|
override fun write(fileHandle: Long, fileOffset: Long, buffer: ByteArray, srcOffset: Long, length: Long): Int {
|
||||||
return nativeWrite(fusePtr, fileHandle, offset, buffer, size)
|
return nativeWrite(fusePtr, fileHandle, fileOffset, buffer, srcOffset, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun truncate(path: String, size: Long): Boolean {
|
override fun truncate(path: String, size: Long): Boolean {
|
||||||
|
@ -74,8 +74,8 @@ abstract class EncryptedVolume: Parcelable {
|
|||||||
override fun describeContents() = 0
|
override fun describeContents() = 0
|
||||||
|
|
||||||
abstract fun openFile(path: String): Long
|
abstract fun openFile(path: String): Long
|
||||||
abstract fun read(fileHandle: Long, buffer: ByteArray, offset: Long): Int
|
abstract fun read(fileHandle: Long, fileOffset: Long, buffer: ByteArray, dstOffset: Long, length: Long): Int
|
||||||
abstract fun write(fileHandle: Long, offset: Long, buffer: ByteArray, size: Int): Int
|
abstract fun write(fileHandle: Long, fileOffset: Long, buffer: ByteArray, srcOffset: Long, length: Long): Int
|
||||||
abstract fun closeFile(fileHandle: Long): Boolean
|
abstract fun closeFile(fileHandle: Long): Boolean
|
||||||
// Due to gocryptfs internals, truncate requires the file to be open before it is called
|
// Due to gocryptfs internals, truncate requires the file to be open before it is called
|
||||||
abstract fun truncate(path: String, size: Long): Boolean
|
abstract fun truncate(path: String, size: Long): Boolean
|
||||||
@ -96,7 +96,7 @@ abstract class EncryptedVolume: Parcelable {
|
|||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE)
|
val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE)
|
||||||
var length: Int
|
var length: Int
|
||||||
while (read(fileHandle, ioBuffer, offset).also { length = it } > 0) {
|
while (read(fileHandle, offset, ioBuffer, 0, ioBuffer.size.toLong()).also { length = it } > 0) {
|
||||||
os.write(ioBuffer, 0, length)
|
os.write(ioBuffer, 0, length)
|
||||||
offset += length.toLong()
|
offset += length.toLong()
|
||||||
}
|
}
|
||||||
@ -132,10 +132,10 @@ abstract class EncryptedVolume: Parcelable {
|
|||||||
var success = true
|
var success = true
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE)
|
val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE)
|
||||||
var length: Int
|
var length: Long
|
||||||
while (inputStream.read(ioBuffer).also { length = it } > 0) {
|
while (inputStream.read(ioBuffer).also { length = it.toLong() } > 0) {
|
||||||
val written = write(dstfileHandle, offset, ioBuffer, length).toLong()
|
val written = write(dstfileHandle, offset, ioBuffer, 0, length).toLong()
|
||||||
if (written == length.toLong()) {
|
if (written == length) {
|
||||||
offset += written
|
offset += written
|
||||||
} else {
|
} else {
|
||||||
inputStream.close()
|
inputStream.close()
|
||||||
@ -174,12 +174,7 @@ abstract class EncryptedVolume: Parcelable {
|
|||||||
Pair(null, 3)
|
Pair(null, 3)
|
||||||
} else {
|
} else {
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
val ioBuffer = ByteArray(ConstValues.IO_BUFF_SIZE)
|
while (offset < fileSize && read(fileHandle, offset, fileBuff, offset, fileSize-offset).also { offset += it } > 0) {}
|
||||||
var length: Int
|
|
||||||
while (read(fileHandle, ioBuffer, offset).also { length = it } > 0) {
|
|
||||||
System.arraycopy(ioBuffer, 0, fileBuff, offset.toInt(), length)
|
|
||||||
offset += length.toLong()
|
|
||||||
}
|
|
||||||
closeFile(fileHandle)
|
closeFile(fileHandle)
|
||||||
if (offset == fileBuff.size.toLong()) {
|
if (offset == fileBuff.size.toLong()) {
|
||||||
Pair(fileBuff, 0)
|
Pair(fileBuff, 0)
|
||||||
|
@ -2,6 +2,7 @@ package sushi.hardcore.droidfs.filesystems
|
|||||||
|
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import sushi.hardcore.droidfs.explorers.ExplorerElement
|
import sushi.hardcore.droidfs.explorers.ExplorerElement
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
class GocryptfsVolume(private val sessionID: Int): EncryptedVolume() {
|
class GocryptfsVolume(private val sessionID: Int): EncryptedVolume() {
|
||||||
private external fun native_close(sessionID: Int)
|
private external fun native_close(sessionID: Int)
|
||||||
@ -9,8 +10,8 @@ class GocryptfsVolume(private val sessionID: Int): EncryptedVolume() {
|
|||||||
private external fun native_list_dir(sessionID: Int, dir_path: String): MutableList<ExplorerElement>?
|
private external fun native_list_dir(sessionID: Int, dir_path: String): MutableList<ExplorerElement>?
|
||||||
private external fun native_open_read_mode(sessionID: Int, file_path: String): Int
|
private external fun native_open_read_mode(sessionID: Int, file_path: String): Int
|
||||||
private external fun native_open_write_mode(sessionID: Int, file_path: String, mode: Int): Int
|
private external fun native_open_write_mode(sessionID: Int, file_path: String, mode: Int): Int
|
||||||
private external fun native_read_file(sessionID: Int, handleID: Int, offset: Long, buff: ByteArray): Int
|
private external fun native_read_file(sessionID: Int, handleID: Int, fileOffset: Long, buff: ByteArray, dstOffset: Long, length: Int): Int
|
||||||
private external fun native_write_file(sessionID: Int, handleID: Int, offset: Long, buff: ByteArray, buff_size: Int): Int
|
private external fun native_write_file(sessionID: Int, handleID: Int, fileOffset: Long, buff: ByteArray, srcOffset: Long, length: Int): Int
|
||||||
private external fun native_truncate(sessionID: Int, path: String, offset: Long): Boolean
|
private external fun native_truncate(sessionID: Int, path: String, offset: Long): Boolean
|
||||||
private external fun native_close_file(sessionID: Int, handleID: Int)
|
private external fun native_close_file(sessionID: Int, handleID: Int)
|
||||||
private external fun native_remove_file(sessionID: Int, file_path: String): Boolean
|
private external fun native_remove_file(sessionID: Int, file_path: String): Boolean
|
||||||
@ -22,6 +23,7 @@ class GocryptfsVolume(private val sessionID: Int): EncryptedVolume() {
|
|||||||
companion object {
|
companion object {
|
||||||
const val KeyLen = 32
|
const val KeyLen = 32
|
||||||
const val ScryptDefaultLogN = 16
|
const val ScryptDefaultLogN = 16
|
||||||
|
const val MAX_KERNEL_WRITE = 128*1024
|
||||||
const val CONFIG_FILE_NAME = "gocryptfs.conf"
|
const val CONFIG_FILE_NAME = "gocryptfs.conf"
|
||||||
external fun createVolume(root_cipher_dir: String, password: ByteArray, plainTextNames: Boolean, xchacha: Int, logN: Int, creator: String, returnedHash: ByteArray?): Boolean
|
external fun createVolume(root_cipher_dir: String, password: ByteArray, plainTextNames: Boolean, xchacha: Int, logN: Int, creator: String, returnedHash: ByteArray?): Boolean
|
||||||
private external fun nativeInit(root_cipher_dir: String, password: ByteArray?, givenHash: ByteArray?, returnedHash: ByteArray?): Int
|
private external fun nativeInit(root_cipher_dir: String, password: ByteArray?, givenHash: ByteArray?, returnedHash: ByteArray?): Int
|
||||||
@ -53,8 +55,8 @@ class GocryptfsVolume(private val sessionID: Int): EncryptedVolume() {
|
|||||||
return native_open_write_mode(sessionID, path, 0).toLong()
|
return native_open_write_mode(sessionID, path, 0).toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(fileHandle: Long, buffer: ByteArray, offset: Long): Int {
|
override fun read(fileHandle: Long, fileOffset: Long, buffer: ByteArray, dstOffset: Long, length: Long): Int {
|
||||||
return native_read_file(sessionID, fileHandle.toInt(), offset, buffer)
|
return native_read_file(sessionID, fileHandle.toInt(), fileOffset, buffer, dstOffset, min(length.toInt(), MAX_KERNEL_WRITE))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun readDir(path: String): MutableList<ExplorerElement>? {
|
override fun readDir(path: String): MutableList<ExplorerElement>? {
|
||||||
@ -91,8 +93,8 @@ class GocryptfsVolume(private val sessionID: Int): EncryptedVolume() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun write(fileHandle: Long, offset: Long, buffer: ByteArray, size: Int): Int {
|
override fun write(fileHandle: Long, fileOffset: Long, buffer: ByteArray, srcOffset: Long, length: Long): Int {
|
||||||
return native_write_file(sessionID, fileHandle.toInt(), offset, buffer, size)
|
return native_write_file(sessionID, fileHandle.toInt(), fileOffset, buffer, srcOffset, min(length.toInt(), MAX_KERNEL_WRITE))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun truncate(path: String, size: Long): Boolean {
|
override fun truncate(path: String, size: Long): Boolean {
|
||||||
|
@ -293,12 +293,12 @@ Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1open_1write_1mod
|
|||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1write_1file(JNIEnv *env, jobject thiz,
|
Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1write_1file(JNIEnv *env, jobject thiz,
|
||||||
jint sessionID, jint handleID, jlong offset,
|
jint sessionID, jint handleID, jlong file_offset,
|
||||||
jbyteArray jbuff, jint buff_size) {
|
jbyteArray jbuff, jlong src_offset, jint length) {
|
||||||
jbyte* buff = (*env)->GetByteArrayElements(env, jbuff, NULL);
|
jbyte* buff = (*env)->GetByteArrayElements(env, jbuff, NULL);
|
||||||
GoSlice go_buff = {buff, buff_size, buff_size};
|
GoSlice go_buff = {buff+src_offset, length, length};
|
||||||
|
|
||||||
int written = gcf_write_file(sessionID, handleID, offset, go_buff);
|
int written = gcf_write_file(sessionID, handleID, file_offset, go_buff);
|
||||||
|
|
||||||
(*env)->ReleaseByteArrayElements(env, jbuff, buff, 0);
|
(*env)->ReleaseByteArrayElements(env, jbuff, buff, 0);
|
||||||
|
|
||||||
@ -307,13 +307,12 @@ Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1write_1file(JNIE
|
|||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1read_1file(JNIEnv *env, jobject thiz,
|
Java_sushi_hardcore_droidfs_filesystems_GocryptfsVolume_native_1read_1file(JNIEnv *env, jobject thiz,
|
||||||
jint sessionID, jint handleID, jlong offset,
|
jint sessionID, jint handleID, jlong file_offset,
|
||||||
jbyteArray jbuff) {
|
jbyteArray jbuff, jlong dst_offset, jint length) {
|
||||||
const size_t buff_size = (*env)->GetArrayLength(env, jbuff);
|
|
||||||
jbyte* buff = (*env)->GetByteArrayElements(env, jbuff, NULL);
|
jbyte* buff = (*env)->GetByteArrayElements(env, jbuff, NULL);
|
||||||
GoSlice go_buff = {buff, buff_size, buff_size};
|
GoSlice go_buff = {buff+dst_offset, length, length};
|
||||||
|
|
||||||
int read = gcf_read_file(sessionID, handleID, offset, go_buff);
|
int read = gcf_read_file(sessionID, handleID, file_offset, go_buff);
|
||||||
|
|
||||||
(*env)->ReleaseByteArrayElements(env, jbuff, buff, 0);
|
(*env)->ReleaseByteArrayElements(env, jbuff, buff, 0);
|
||||||
return read;
|
return read;
|
||||||
|
@ -35,10 +35,15 @@ Java_sushi_hardcore_droidfs_filesystems_CryfsVolume_00024Companion_nativeOpen(JN
|
|||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_sushi_hardcore_droidfs_filesystems_CryfsVolume_00024Companion_nativeRead(JNIEnv *env, jobject thiz,
|
Java_sushi_hardcore_droidfs_filesystems_CryfsVolume_00024Companion_nativeRead(JNIEnv *env,
|
||||||
jlong fuse_ptr, jlong file_handle,
|
jobject thiz,
|
||||||
jbyteArray buffer, jlong offset) {
|
jlong fuse_ptr,
|
||||||
return cryfs_read(env, fuse_ptr, file_handle, buffer, offset);
|
jlong file_handle,
|
||||||
|
jlong file_offset,
|
||||||
|
jbyteArray buffer,
|
||||||
|
jlong dst_offset,
|
||||||
|
jlong length) {
|
||||||
|
return cryfs_read(env, fuse_ptr, file_handle, file_offset, buffer, dst_offset, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
@ -46,10 +51,11 @@ Java_sushi_hardcore_droidfs_filesystems_CryfsVolume_00024Companion_nativeWrite(J
|
|||||||
jobject thiz,
|
jobject thiz,
|
||||||
jlong fuse_ptr,
|
jlong fuse_ptr,
|
||||||
jlong file_handle,
|
jlong file_handle,
|
||||||
jlong offset,
|
jlong file_offset,
|
||||||
jbyteArray buffer,
|
jbyteArray buffer,
|
||||||
jint size) {
|
jlong src_offset,
|
||||||
return cryfs_write(env, fuse_ptr, file_handle, offset, buffer, size);
|
jlong length) {
|
||||||
|
return cryfs_write(env, fuse_ptr, file_handle, file_offset, buffer, src_offset, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Loading…
Reference in New Issue
Block a user