[Android Software/Hacking General [Developers Only]] llrraa2010:
Ashmem driver--read/write

public class MemoryFile

{

......

private static native int native_read(FileDescriptor fd, int address, byte[] buffer,

int srcOffset, int destOffset, int count, boolean isUnpinned) throws IOException;

private static native void native_write(FileDescriptor fd, int address, byte[] buffer,

int srcOffset, int destOffset, int count, boolean isUnpinned) throws IOException;

......

private FileDescriptor mFD; // ashmem file descriptor

private int mAddress; // address of ashmem memory

private int mLength; // total length of our ashmem region

private boolean mAllowPurging = false; // true if our ashmem region is unpinned

......

/**

* Reads bytes from the memory file.

* Will throw an IOException if the file has been purged.

*

* [MENTION=955119]param[/MENTION] buffer byte array to read bytes into.

* [MENTION=955119]param[/MENTION] srcOffset offset into the memory file to read from.

* [MENTION=955119]param[/MENTION] destOffset offset into the byte array buffer to read into.

* [MENTION=955119]param[/MENTION] count number of bytes to read.

* [MENTION=2056652]return[/MENTION] number of bytes read.

* [MENTION=948141]Throw[/MENTION]s IOException if the memory file has been purged or deactivated.

*/

public int readBytes(byte[] buffer, int srcOffset, int destOffset, int count)

throws IOException {

if (isDeactivated()) {

throw new IOException("Can't read from deactivated memory file.");

}

if (destOffset < 0 || destOffset > buffer.length || count < 0

|| count > buffer.length - destOffset

|| srcOffset < 0 || srcOffset > mLength

|| count > mLength - srcOffset) {

throw new IndexOutOfBoundsException();

}

return native_read(mFD, mAddress, buffer, srcOffset, destOffset, count, mAllowPurging);

}

/**

* Write bytes to the memory file.

* Will throw an IOException if the file has been purged.

*

* [MENTION=955119]param[/MENTION] buffer byte array to write bytes from.

* [MENTION=955119]param[/MENTION] srcOffset offset into the byte array buffer to write from.

* [MENTION=955119]param[/MENTION] destOffset offset into the memory file to write to.

* [MENTION=955119]param[/MENTION] count number of bytes to write.

* [MENTION=948141]Throw[/MENTION]s IOException if the memory file has been purged or deactivated.

*/

public void writeBytes(byte[] buffer, int srcOffset, int destOffset, int count)

throws IOException {

if (isDeactivated()) {

throw new IOException("Can't write to deactivated memory file.");

}

if (srcOffset < 0 || srcOffset > buffer.length || count < 0

|| count > buffer.length - srcOffset

|| destOffset < 0 || destOffset > mLength

|| count > mLength - destOffset) {

throw new IndexOutOfBoundsException();

}

native_write(mFD, mAddress, buffer, srcOffset, destOffset, count, mAllowPurging);

}

......

}

frameworks/base/core/jni/adroid_os_MemoryFile.cpp

static jint android_os_MemoryFile_read(JNIEnv* env, jobject clazz,

jobject fileDescriptor, jint address, jbyteArray buffer, jint srcOffset, jint destOffset,

jint count, jboolean unpinned)

{

int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

if (unpinned && ashmem_pin_region(fd, 0, 0) == ASHMEM_WAS_PURGED) {

ashmem_unpin_region(fd, 0, 0);

jniThrowException(env, "java/io/IOException", "ashmem region was purged");

return -1;

}

env->SetByteArrayRegion(buffer, destOffset, count, (const jbyte *)address + srcOffset);

if (unpinned) {

ashmem_unpin_region(fd, 0, 0);

}

return count;

}

static jint android_os_MemoryFile_write(JNIEnv* env, jobject clazz,

jobject fileDescriptor, jint address, jbyteArray buffer, jint srcOffset, jint destOffset,

jint count, jboolean unpinned)

{

int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

if (unpinned && ashmem_pin_region(fd, 0, 0) == ASHMEM_WAS_PURGED) {

ashmem_unpin_region(fd, 0, 0);

jniThrowException(env, "java/io/IOException", "ashmem region was purged");

return -1;

}

env->GetByteArrayRegion(buffer, srcOffset, count, (jbyte *)address + destOffset);

if (unpinned) {

ashmem_unpin_region(fd, 0, 0);

}

return count;

}