/* * Class: jmdb_DatabaseWrapper * Method: cursorGet * Signature: (J[BII[BIII)V */ JNIEXPORT jlong JNICALL Java_jmdb_DatabaseWrapper_cursorGet(JNIEnv *vm, jclass clazz, jlong cursorL, jbyteArray keyA, jint kofs, jint klen, jbyteArray valueA, jint vofs, jint vlen, jint op) { MDB_cursor *cursorC = (MDB_cursor*) cursorL; enum { NONE, OOM, MDB, IOOB } result = NONE; jlong ret; jint code; char lenHolder[64]; MDB_val key, value; jbyte *keyC = (*vm)->GetPrimitiveArrayCritical(vm, keyA, NULL); jbyte *valueC = (*vm)->GetPrimitiveArrayCritical(vm, valueA, NULL); if (keyC == NULL || valueC == NULL) { result = OOM; ret = -1; code = 0; } else { key.mv_size = klen; key.mv_data = keyC + kofs; value.mv_size = 0; code = mdb_cursor_get(cursorC, &key, &value, op); if (code == MDB_NOTFOUND) { ret = -1; } else if (code) { result = MDB; } else if ((jlong) value.mv_size > vlen) { sprintf(lenHolder, "V%d/%d", (int ) value.mv_size, vlen); result = IOOB; } else if ((jlong) key.mv_size > klen) { sprintf(lenHolder, "K%d/%d", (int ) key.mv_size, klen); result = IOOB; } else { memcpy(keyC + kofs, key.mv_data, key.mv_size); memcpy(valueC + vofs, value.mv_data, value.mv_size); ret = ((((jlong) key.mv_size) & 0xffffffff) << 32) + (((jlong) value.mv_size) & 0xffffffff); } } (*vm)->ReleasePrimitiveArrayCritical(vm, valueA, valueC, 0); (*vm)->ReleasePrimitiveArrayCritical(vm, keyA, keyC, 0); switch (result) { case NONE: return ret; case OOM: throwNew(vm, "java/lang/OutOfMemoryError", ""); return -1; case MDB: throwDatabaseException(vm, code); return -1; case IOOB: throwNew(vm, "java/lang/IndexOutOfBoundsException", lenHolder); return -1; default: throwNew(vm, "java/lang/RuntimeException", "Flow control error in jni"); return -1; } }
/* * Class: jmdb_DatabaseWrapper * Method: get * Signature: (JI[BII[BII)I */ JNIEXPORT jint JNICALL Java_jmdb_DatabaseWrapper_get(JNIEnv *vm, jclass clazz, jlong txnL, jint dbi, jbyteArray keyA, jint kofs, jint klen, jbyteArray valueA, jint vofs, jint vlen) { MDB_txn *txnC = (MDB_txn*) txnL; enum { NONE, OOM, MDB, IOOB } result = NONE; jint ret; char lenHolder[64]; MDB_val key, value; jbyte *keyC = (*vm)->GetPrimitiveArrayCritical(vm, keyA, NULL); jbyte *valueC = (*vm)->GetPrimitiveArrayCritical(vm, valueA, NULL); if (keyC == NULL || valueC == NULL) { result = OOM; ret = -1; } else { key.mv_size = klen; key.mv_data = keyC + kofs; ret = mdb_get(txnC, (MDB_dbi) dbi, &key, &value); if (ret == MDB_NOTFOUND) { ret = -1; } else if (ret) { result = MDB; } else if ((jlong) value.mv_size > vlen) { sprintf(lenHolder, "V%d/%d", (int ) value.mv_size, vlen); result = IOOB; } else if ((jlong) key.mv_size > klen) { sprintf(lenHolder, "K%d/%d", (int ) key.mv_size, klen); result = IOOB; } else { memcpy(valueC + vofs, value.mv_data, value.mv_size); ret = value.mv_size; } } (*vm)->ReleasePrimitiveArrayCritical(vm, valueA, valueC, 0); (*vm)->ReleasePrimitiveArrayCritical(vm, keyA, keyC, JNI_ABORT); switch (result) { case NONE: return ret; case OOM: throwNew(vm, "java/lang/OutOfMemoryError", ""); return -1; case MDB: throwDatabaseException(vm, ret); return -1; case IOOB: throwNew(vm, "java/lang/IndexOutOfBoundsException", lenHolder); return -1; default: throwNew(vm, "java/lang/RuntimeException", "Flow control error in jni"); return -1; } }
/* * Class: jmdb_DatabaseWrapper * Method: del * Signature: (JI[BII[BII)V */ JNIEXPORT jboolean JNICALL Java_jmdb_DatabaseWrapper_del(JNIEnv *vm, jclass clazz, jlong txnL, jint dbi, jbyteArray keyA, jint kofs, jint klen, jbyteArray valueA, jint vofs, jint vlen) { MDB_txn *txnC = (MDB_txn*) txnL; enum { NONE, OOM, MDB } result = NONE; jint ret; MDB_val key, value; jbyte *keyC = (*vm)->GetPrimitiveArrayCritical(vm, keyA, NULL); jbyte *valueC = valueA ? (*vm)->GetPrimitiveArrayCritical(vm, valueA, NULL) : NULL; if (keyC == NULL || (valueA && valueC == NULL)) { result = OOM; ret = 0; //make gcc happy } else { key.mv_size = klen; key.mv_data = keyC + kofs; if (valueA) { value.mv_size = vlen; value.mv_data = valueC + vofs; ret = mdb_del(txnC, (MDB_dbi) dbi, &key, &value); } else { ret = mdb_del(txnC, (MDB_dbi) dbi, &key, NULL); } if (ret == MDB_NOTFOUND) { ret = 0; } else if (ret) { result = MDB; } else { ret = 1; } } if (valueA) { (*vm)->ReleasePrimitiveArrayCritical(vm, valueA, valueC, 0); } (*vm)->ReleasePrimitiveArrayCritical(vm, keyA, keyC, JNI_ABORT); switch (result) { case NONE: return ret; case OOM: throwNew(vm, "java/lang/OutOfMemoryError", ""); return 0; case MDB: throwDatabaseException(vm, ret); return 0; default: throwNew(vm, "java/lang/RuntimeException", "Flow control error in jni"); return 0; } }
SOCKET accept(JNIEnv* e, SOCKET sock, long* client_addr, short* client_port) { sockaddr_in adr; SOCKET client_socket = ::accept(sock, (sockaddr*)&adr, NULL); if (INVALID_SOCKET == client_socket) { char buf[255]; sprintf(buf, "Can't accept the incoming connection. System error: %d", last_socket_error()); throwNew(e, "java/io/IOException", buf); return INVALID_SOCKET; } if (client_addr != NULL) { #ifdef PLATFORM_WINDOWS *client_addr = ntohl(adr.sin_addr.S_un.S_addr); #else *client_addr = ntohl(adr.sin_addr.s_addr); #endif } if (client_port != NULL) { *client_port = ntohs(adr.sin_port); } return client_socket; }
/* * Class: jmdb_DatabaseWrapper * Method: envInfo * Signature: (JLjava/nio/ByteBuffer;)V */ JNIEXPORT void JNICALL Java_jmdb_DatabaseWrapper_envInfo(JNIEnv *vm, jclass clazz, jlong envL, jobject buf) { MDB_env *envC = (MDB_env*) envL; MDB_envinfo info; jsize size = (*vm)->GetArrayLength(vm, buf); jlong *bufC; if (size < JMDB_INFO_SIZE) { throwNew(vm, "java/lang/IndexOutOfBoundsException", "info[]'s length is less than MDB_info's entries"); return; } int code = mdb_env_info(envC, &info); if (code) { throwDatabaseException(vm, code); return; } bufC = (*vm)->GetPrimitiveArrayCritical(vm, buf, NULL); bufC[0] = (jlong) info.me_mapaddr; bufC[1] = (jlong) info.me_mapsize; bufC[2] = (jlong) info.me_last_pgno; bufC[3] = (jlong) info.me_last_txnid; bufC[4] = (jlong) info.me_maxreaders; bufC[5] = (jlong) info.me_numreaders; (*vm)->ReleasePrimitiveArrayCritical(vm, buf, bufC, 0); }
/* * Class: jmdb_DatabaseWrapper * Method: stat * Signature: (JILjava/nio/ByteBuffer;)V */ JNIEXPORT void JNICALL Java_jmdb_DatabaseWrapper_stat(JNIEnv *vm, jclass clazz, jlong txnL, jint dbi, jobject buf) { MDB_txn *txnC = (MDB_txn*) txnL; MDB_stat stat; jsize size = (*vm)->GetArrayLength(vm, buf); jlong *bufC; if (size < JMDB_STAT_SIZE) { throwNew(vm, "java/lang/IndexOutOfBoundsException", "stat[]'s length is less than MDB_stat's entries"); return; } int code = mdb_stat(txnC, (MDB_dbi) dbi, &stat); if (code) { throwDatabaseException(vm, code); return; } bufC = (*vm)->GetPrimitiveArrayCritical(vm, buf, NULL); bufC[0] = stat.ms_psize; bufC[1] = stat.ms_depth; bufC[2] = stat.ms_branch_pages; bufC[3] = stat.ms_leaf_pages; bufC[4] = stat.ms_overflow_pages; bufC[5] = stat.ms_entries; (*vm)->ReleasePrimitiveArrayCritical(vm, buf, bufC, 0); }
extern "C" JNIEXPORT void JNICALL Java_java_util_zip_Deflater_deflate(JNIEnv* e, jclass, jlong peer, jbyteArray input, jint inputOffset, jint inputLength, jbyteArray output, jint outputOffset, jint outputLength, jboolean finish, jintArray results) { z_stream* s = reinterpret_cast<z_stream*>(peer); jbyte* in = static_cast<jbyte*>(malloc(inputLength)); if (in == 0) { throwNew(e, "java/lang/OutOfMemoryError", 0); return; } jbyte* out = static_cast<jbyte*>(malloc(outputLength)); if (out == 0) { free(in); throwNew(e, "java/lang/OutOfMemoryError", 0); return; } e->GetByteArrayRegion(input, inputOffset, inputLength, in); s->next_in = reinterpret_cast<Bytef*>(in); s->avail_in = inputLength; s->next_out = reinterpret_cast<Bytef*>(out); s->avail_out = outputLength; int r = deflate(s, finish ? Z_FINISH : Z_NO_FLUSH); jint resultArray[3] = {r, static_cast<jint>(inputLength - s->avail_in), static_cast<jint>(outputLength - s->avail_out)}; free(in); e->SetByteArrayRegion(output, outputOffset, resultArray[2], out); free(out); e->SetIntArrayRegion(results, 0, 3, resultArray); }
void abort(JNIEnv* e, SOCKET sock) { if (SOCKET_ERROR == ::closesocket(sock)) { char buf[255]; sprintf( buf, "Can't close the socket. System error: %d", last_socket_error()); throwNew(e, "java/io/IOException", buf); } }
void send(JNIEnv* e, SOCKET sock, const char* buff_ptr, int buff_size) { if (SOCKET_ERROR == ::send(sock, buff_ptr, buff_size, 0)) { char buf[255]; sprintf(buf, "Can't send data through the socket. System error: %d", last_socket_error()); throwNew(e, "java/io/IOException", buf); return; } }
extern "C" JNIEXPORT jint JNICALL Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid) { #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) DWORD exitCode; WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE); BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode); if (not success) { throwNew(e, "java/lang/Exception", getErrorStr(GetLastError())); } CloseHandle(reinterpret_cast<HANDLE>(pid)); CloseHandle(reinterpret_cast<HANDLE>(tid)); return exitCode; #else throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8")); return -1; #endif }
void close_output(JNIEnv* e, SOCKET sock) { if (SOCKET_ERROR == ::shutdown(sock, SD_SEND)) { int errcode = last_socket_error(); if (errcode != ENOTCONN) { char buf[255]; sprintf(buf, "Can't shutdown the socket. System error: %d", errcode); throwNew(e, "java/io/IOException", buf); } } }
JNIEXPORT void JNICALL Java_quickfix_SocketAcceptor_start ( JNIEnv *pEnv, jobject obj ) { QF_STACK_TRY JVM::set( pEnv ); try { getCPPSocketAcceptor( obj ) ->start(); } catch( FIX::ConfigError &e ) { throwNew( "Lquickfix/ConfigError;", e.what() ); } catch( FIX::RuntimeError &e ) { throwNew( "Lquickfix/RuntimeError;", e.what() ); } QF_STACK_CATCH }
extern "C" JNIEXPORT jlong JNICALL Java_java_util_zip_Inflater_make(JNIEnv* e, jclass, jboolean nowrap) { z_stream* s = static_cast<z_stream*>(malloc(sizeof(z_stream))); if (s == 0) { throwNew(e, "java/lang/OutOfMemoryError", 0); return 0; } memset(s, 0, sizeof(z_stream)); int r = inflateInit2(s, (nowrap ? -15 : 15)); if (r != Z_OK) { free(s); throwNew(e, "java/lang/RuntimeException", zError(r)); return 0; } return reinterpret_cast<jlong>(s); }
JNIEXPORT void JNICALL Java_quickfix_ThreadedSocketInitiator_block ( JNIEnv *pEnv, jobject obj ) { QF_STACK_TRY JVM::set( pEnv ); try { getCPPThreadedSocketInitiator( obj ) ->block(); } catch( FIX::ConfigError &e ) { throwNew( "Lquickfix/ConfigError;", e.what() ); } catch( FIX::RuntimeError &e ) { throwNew( "Lquickfix/RuntimeError;", e.what() ); } QF_STACK_CATCH }
JNIEXPORT jboolean JNICALL Java_quickfix_ThreadedSocketInitiator_poll ( JNIEnv *pEnv, jobject obj ) { QF_STACK_TRY JVM::set( pEnv ); try { return getCPPThreadedSocketInitiator( obj ) ->poll(); } catch( FIX::ConfigError &e ) { throwNew( "Lquickfix/ConfigError;", e.what() ); } catch( FIX::RuntimeError &e ) { throwNew( "Lquickfix/RuntimeError;", e.what() ); } return false; QF_STACK_CATCH }
SOCKET create(JNIEnv* e) { SOCKET sock; if (INVALID_SOCKET == (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) { char buf[255]; sprintf( buf, "Can't create a socket. System error: %d", last_socket_error()); throwNew(e, "java/io/IOException", buf); return 0; // This doesn't matter cause we have risen an exception } return sock; }
int recv(JNIEnv* e, SOCKET sock, char* buff_ptr, int buff_size) { int length = ::recv(sock, buff_ptr, buff_size, 0); if (SOCKET_ERROR == length) { char buf[255]; sprintf(buf, "Can't receive data through the socket. System error: %d", last_socket_error()); throwNew(e, "java/io/IOException", buf); return 0; // This doesn't matter cause we have risen an exception } return length; }
void init(JNIEnv* ONLY_ON_WINDOWS(e)) { #ifdef PLATFORM_WINDOWS static bool wsaInitialized = false; if (not wsaInitialized) { WSADATA data; int r = WSAStartup(MAKEWORD(2, 2), &data); if (r or LOBYTE(data.wVersion) != 2 or HIBYTE(data.wVersion) != 2) { throwNew(e, "java/io/IOException", "WSAStartup failed"); } else { wsaInitialized = true; } } #endif }
extern "C" JNIEXPORT jint JNICALL Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid) { DWORD exitCode; WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE); BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode); if(not success){ throwNew(e, "java/lang/Exception", getErrorStr(GetLastError())); } CloseHandle(reinterpret_cast<HANDLE>(pid)); CloseHandle(reinterpret_cast<HANDLE>(tid)); return exitCode; }
extern "C" JNIEXPORT jlong JNICALL Java_java_nio_channels_SocketSelector_natInit(JNIEnv* e, jclass) { void *mem = malloc(sizeof(SelectorState)); if (mem) { SelectorState *s = new (mem) SelectorState(e); if (e->ExceptionCheck()) return 0; if (s) { FD_ZERO(&(s->read)); FD_ZERO(&(s->write)); FD_ZERO(&(s->except)); return reinterpret_cast<jlong>(s); } } throwNew(e, "java/lang/OutOfMemoryError", 0); return 0; }
void bind(JNIEnv* e, SOCKET sock, long addr, short port) { sockaddr_in adr; adr.sin_family = AF_INET; #ifdef PLATFORM_WINDOWS adr.sin_addr.S_un.S_addr = htonl(addr); #else adr.sin_addr.s_addr = htonl(addr); #endif adr.sin_port = htons(port); if (SOCKET_ERROR == ::bind(sock, (sockaddr*)&adr, sizeof(adr))) { char buf[255]; sprintf(buf, "Can't bind a socket. System error: %d", last_socket_error()); throwNew(e, "java/io/IOException", buf); return; } }
JNIEXPORT void JNICALL Java_quickfix_ThreadedSocketInitiator_create ( JNIEnv *pEnv, jobject obj ) { QF_STACK_TRY JVM::set( pEnv ); JVMObject jobject( obj ); JavaLogFactory* pLogFactory = 0; try { pLogFactory = &createLogFactory( jobject ); } catch ( JVMException& ) {} FIX::Initiator* pInitiator = 0; try { if ( pLogFactory ) { pInitiator = new FIX::ThreadedSocketInitiator( createApplication( jobject ), createFactory( jobject ), getSettings( jobject ), *pLogFactory ); } else { pInitiator = new FIX::ThreadedSocketInitiator( createApplication( jobject ), createFactory( jobject ), getSettings( jobject )); } } catch( FIX::ConfigError& e ) { throwNew( "Lquickfix/ConfigError;", e.what() ); return; } jobject.setLong( "cppPointer", ( long ) pInitiator ); QF_STACK_CATCH }
/* * Class: jmdb_DatabaseWrapper * Method: cursorPut * Signature: (J[BII[BIII)V */ JNIEXPORT void JNICALL Java_jmdb_DatabaseWrapper_cursorPut(JNIEnv *vm, jclass clazz, jlong cursorL, jbyteArray keyA, jint kofs, jint klen, jbyteArray valueA, jint vofs, jint vlen, jint flags) { MDB_cursor *cursorC = (MDB_cursor*) cursorL; enum { NONE, OOM, MDB } result = NONE; jint ret; MDB_val key, value; jbyte *keyC = (*vm)->GetPrimitiveArrayCritical(vm, keyA, NULL); jbyte *valueC = (*vm)->GetPrimitiveArrayCritical(vm, valueA, NULL); if (keyC == NULL || valueC == NULL) { result = OOM; ret = -1; } else { key.mv_size = klen; key.mv_data = keyC + kofs; value.mv_size = vlen; value.mv_data = valueC + vofs; ret = mdb_cursor_put(cursorC, &key, &value, (unsigned int) flags); if (ret) { result = MDB; } } (*vm)->ReleasePrimitiveArrayCritical(vm, valueA, valueC, 0); (*vm)->ReleasePrimitiveArrayCritical(vm, keyA, keyC, JNI_ABORT); switch (result) { case NONE: return; case OOM: throwNew(vm, "java/lang/OutOfMemoryError", ""); return; case MDB: throwDatabaseException(vm, ret); return; } }
extern "C" JNIEXPORT void JNICALL Java_java_lang_Runtime_exec(JNIEnv* e, jclass, jobjectArray command, jlongArray process) { int size = 0; for (int i = 0; i < e->GetArrayLength(command); ++i){ jstring element = (jstring) e->GetObjectArrayElement(command, i); size += e->GetStringUTFLength(element) + 1; } RUNTIME_ARRAY(char, line, size); char* linep = RUNTIME_ARRAY_BODY(line); for (int i = 0; i < e->GetArrayLength(command); ++i) { if (i) *(linep++) = _T(' '); jstring element = (jstring) e->GetObjectArrayElement(command, i); const char* s = e->GetStringUTFChars(element, 0); #ifdef _MSC_VER _tcscpy_s(linep, size - (linep - RUNTIME_ARRAY_BODY(line)), s); #else _tcscpy(linep, s); #endif e->ReleaseStringUTFChars(element, s); linep += e->GetStringUTFLength(element); } *(linep++) = _T('\0'); HANDLE in[] = { 0, 0 }; HANDLE out[] = { 0, 0 }; HANDLE err[] = { 0, 0 }; makePipe(e, in); SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0); jlong inDescriptor = static_cast<jlong>(descriptor(e, in[0])); if(e->ExceptionCheck()) return; e->SetLongArrayRegion(process, 2, 1, &inDescriptor); makePipe(e, out); SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0); jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1])); if(e->ExceptionCheck()) return; e->SetLongArrayRegion(process, 3, 1, &outDescriptor); makePipe(e, err); SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0); jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0])); if(e->ExceptionCheck()) return; e->SetLongArrayRegion(process, 4, 1, &errDescriptor); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdOutput = in[1]; si.hStdInput = out[0]; si.hStdError = err[1]; BOOL success = CreateProcess(0, (LPSTR) RUNTIME_ARRAY_BODY(line), 0, 0, 1, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, 0, 0, &si, &pi); CloseHandle(in[1]); CloseHandle(out[0]); CloseHandle(err[1]); if (not success) { throwNew(e, "java/io/IOException", getErrorStr(GetLastError())); return; } jlong pid = reinterpret_cast<jlong>(pi.hProcess); e->SetLongArrayRegion(process, 0, 1, &pid); jlong tid = reinterpret_cast<jlong>(pi.hThread); e->SetLongArrayRegion(process, 1, 1, &tid); }
extern "C" JNIEXPORT void JNICALL Java_java_lang_Runtime_exec(JNIEnv* e, jclass, jobjectArray command, jlongArray process) { #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) int size = 0; for (int i = 0; i < e->GetArrayLength(command); ++i) { jstring element = (jstring)e->GetObjectArrayElement(command, i); if (element) { // worst case, assuming every character is '"', and we escape all of them size += 2 * e->GetStringUTFLength(element) + 3; } else { throwNew(e, "java/lang/NullPointerException", strdup("null string array element")); } } RUNTIME_ARRAY(char, line, size); char* linep = RUNTIME_ARRAY_BODY(line); for (int i = 0; i < e->GetArrayLength(command); ++i) { if (i) *(linep++) = _T(' '); jstring element = (jstring)e->GetObjectArrayElement(command, i); const char* s = e->GetStringUTFChars(element, 0); copyAndEscape(&linep, s, e->GetStringUTFLength(element)); e->ReleaseStringUTFChars(element, s); } *(linep++) = _T('\0'); HANDLE in[] = {0, 0}; HANDLE out[] = {0, 0}; HANDLE err[] = {0, 0}; makePipe(e, in); SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0); jlong inDescriptor = static_cast<jlong>(descriptor(e, in[0])); if (e->ExceptionCheck()) return; e->SetLongArrayRegion(process, 2, 1, &inDescriptor); makePipe(e, out); SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0); jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1])); if (e->ExceptionCheck()) return; e->SetLongArrayRegion(process, 3, 1, &outDescriptor); makePipe(e, err); SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0); jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0])); if (e->ExceptionCheck()) return; e->SetLongArrayRegion(process, 4, 1, &errDescriptor); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdOutput = in[1]; si.hStdInput = out[0]; si.hStdError = err[1]; BOOL success = CreateProcess(0, (LPSTR)RUNTIME_ARRAY_BODY(line), 0, 0, 1, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, 0, 0, &si, &pi); CloseHandle(in[1]); CloseHandle(out[0]); CloseHandle(err[1]); if (not success) { throwNew(e, "java/io/IOException", getErrorStr(GetLastError())); return; } jlong pid = reinterpret_cast<jlong>(pi.hProcess); e->SetLongArrayRegion(process, 0, 1, &pid); jlong tid = reinterpret_cast<jlong>(pi.hThread); e->SetLongArrayRegion(process, 1, 1, &tid); #else throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8")); #endif }