diff --git a/wince/org.eclipse.tm.rapi.examples/src/org/eclipse/tm/rapi/examples/RapiExamples.java b/wince/org.eclipse.tm.rapi.examples/src/org/eclipse/tm/rapi/examples/RapiExamples.java index c25d0632f4a..90eb6ba53ec 100644 --- a/wince/org.eclipse.tm.rapi.examples/src/org/eclipse/tm/rapi/examples/RapiExamples.java +++ b/wince/org.eclipse.tm.rapi.examples/src/org/eclipse/tm/rapi/examples/RapiExamples.java @@ -15,6 +15,7 @@ import org.eclipse.tm.rapi.IRapiDevice; import org.eclipse.tm.rapi.IRapiEnumDevices; import org.eclipse.tm.rapi.IRapiSession; import org.eclipse.tm.rapi.OS; +import org.eclipse.tm.rapi.ProcessInformation; import org.eclipse.tm.rapi.RapiConnectionInfo; import org.eclipse.tm.rapi.RapiDeviceInfo; import org.eclipse.tm.rapi.RapiException; @@ -194,6 +195,22 @@ public class RapiExamples { } } + /** + * Opens the specified URL in a browser. The browser is started with + * {@link IRapiSession#createProcess(String, String, int)} and the URL + * is passed as command line argument. + */ + void openUrl(String url) throws RapiException { + System.out.println(">>> openUrl() url: " + url); + ProcessInformation pi = session.createProcess("\\Windows\\iexplore.exe", url, 0); + System.out.println("hProcess: " + Integer.toHexString(pi.hProcess)); + System.out.println("hThread: " + Integer.toHexString(pi.hThread)); + System.out.println("dwProcessId: " + Integer.toHexString(pi.dwProcessId)); + System.out.println("dwThreadId: " + Integer.toHexString(pi.dwThreadId)); + session.closeHandle(pi.hProcess); + session.closeHandle(pi.hThread); + } + void runExamples() { try { initRapi(); @@ -216,6 +233,7 @@ public class RapiExamples { statFile("\\foo.txt"); System.out.println(">>> printDeviceTree()"); printDeviceTree("\\", 0); + openUrl("www.eclipse.org/dsdp/tm"); session.uninit(); } catch (RapiException e) { e.printStackTrace(); diff --git a/wince/org.eclipse.tm.rapi/lib/os/win32/x86/jrapi.dll b/wince/org.eclipse.tm.rapi/lib/os/win32/x86/jrapi.dll index 3bf88191959..949cb837440 100644 Binary files a/wince/org.eclipse.tm.rapi/lib/os/win32/x86/jrapi.dll and b/wince/org.eclipse.tm.rapi/lib/os/win32/x86/jrapi.dll differ diff --git a/wince/org.eclipse.tm.rapi/native/RapiSession.cpp b/wince/org.eclipse.tm.rapi/native/RapiSession.cpp index 0d443e1b4c2..350892f17df 100644 --- a/wince/org.eclipse.tm.rapi/native/RapiSession.cpp +++ b/wince/org.eclipse.tm.rapi/native/RapiSession.cpp @@ -435,4 +435,62 @@ fail: if (arg3 && lparg3) env->ReleaseLongArrayElements(arg3, lparg3, 0); if (arg4 && lparg4) env->ReleaseLongArrayElements(arg4, lparg4, 0); return rc; +} + +struct PROCESS_INFORMATION_FID_CACHE +{ + int cached; + jclass clazz; + jfieldID hProcess, hThread; + jfieldID dwProcessId, dwThreadId; +}; + +PROCESS_INFORMATION_FID_CACHE PROCESS_INFORMATIONFc; + +void cachePROCESS_INFORMATIONFields(JNIEnv *env, jobject lpObject) +{ + if (PROCESS_INFORMATIONFc.cached) return; + PROCESS_INFORMATIONFc.clazz = env->GetObjectClass(lpObject); + PROCESS_INFORMATIONFc.hProcess = env->GetFieldID(PROCESS_INFORMATIONFc.clazz, "hProcess", "I"); + PROCESS_INFORMATIONFc.hThread = env->GetFieldID(PROCESS_INFORMATIONFc.clazz, "hThread", "I"); + PROCESS_INFORMATIONFc.dwProcessId = env->GetFieldID(PROCESS_INFORMATIONFc.clazz, "dwProcessId", "I"); + PROCESS_INFORMATIONFc.dwThreadId = env->GetFieldID(PROCESS_INFORMATIONFc.clazz, "dwThreadId", "I"); + PROCESS_INFORMATIONFc.cached = 1; +} + +void setPROCESS_INFORMATIONFields(JNIEnv *env, jobject lpObject, PROCESS_INFORMATION *pi) +{ + if (!PROCESS_INFORMATIONFc.cached) cachePROCESS_INFORMATIONFields(env, lpObject); + env->SetIntField(lpObject, PROCESS_INFORMATIONFc.hProcess, (jint)pi->hProcess); + env->SetIntField(lpObject, PROCESS_INFORMATIONFc.hThread, (jint)pi->hThread); + env->SetIntField(lpObject, PROCESS_INFORMATIONFc.dwProcessId, (jint)pi->dwProcessId); + env->SetIntField(lpObject, PROCESS_INFORMATIONFc.dwThreadId, (jint)pi->dwThreadId); +} + +JNIEXPORT jboolean JNICALL RAPI_NATIVE(CeCreateProcess) + (JNIEnv *env, jobject that, jint arg0, jstring arg1, jstring arg2, jint arg3, jobject arg4) +{ + jboolean rc = 0; + const jchar *lparg1 = NULL; + const jchar *lparg2 = NULL; + PROCESS_INFORMATION pi; + + if (arg0 == 0) return 0; + if (arg1) { + lparg1 = env->GetStringChars(arg1, NULL); + if (lparg1 == NULL) goto fail; + } + if (arg2) { + lparg2 = env->GetStringChars(arg2, NULL); + if (lparg2 == NULL) goto fail; + } + IRAPISession *pSession = (IRAPISession*) arg0; + rc = pSession->CeCreateProcess((LPCWSTR)lparg1, (LPCWSTR)lparg2, NULL, NULL, FALSE, arg3, NULL, NULL, NULL, &pi); + if (!rc) goto fail; + if (arg4) setPROCESS_INFORMATIONFields(env, arg4, &pi); + +fail: + if (arg1 && lparg1) env->ReleaseStringChars(arg1, lparg1); + if (arg2 && lparg2) env->ReleaseStringChars(arg2, lparg2); + return rc; } \ No newline at end of file diff --git a/wince/org.eclipse.tm.rapi/native/org_eclipse_tm_internal_rapi_RapiSession.h b/wince/org.eclipse.tm.rapi/native/org_eclipse_tm_internal_rapi_RapiSession.h index eba6404ecb7..ce71e9b41f1 100644 --- a/wince/org.eclipse.tm.rapi/native/org_eclipse_tm_internal_rapi_RapiSession.h +++ b/wince/org.eclipse.tm.rapi/native/org_eclipse_tm_internal_rapi_RapiSession.h @@ -175,6 +175,14 @@ JNIEXPORT jint JNICALL Java_org_eclipse_tm_internal_rapi_RapiSession_CeGetFileSi JNIEXPORT jboolean JNICALL Java_org_eclipse_tm_internal_rapi_RapiSession_CeGetFileTime (JNIEnv *, jobject, jint, jint, jlongArray, jlongArray, jlongArray); +/* + * Class: org_eclipse_tm_internal_rapi_RapiSession + * Method: CeCreateProcess + * Signature: (ILjava/lang/String;Ljava/lang/String;ILorg/eclipse/tm/rapi/ProcessInformation;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_eclipse_tm_internal_rapi_RapiSession_CeCreateProcess + (JNIEnv *, jobject, jint, jstring, jstring, jint, jobject); + #ifdef __cplusplus } #endif diff --git a/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/internal/rapi/RapiSession.java b/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/internal/rapi/RapiSession.java index 784c9d44242..bb5074f1513 100644 --- a/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/internal/rapi/RapiSession.java +++ b/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/internal/rapi/RapiSession.java @@ -14,6 +14,7 @@ import java.util.Date; import org.eclipse.tm.rapi.IRapiSession; import org.eclipse.tm.rapi.OS; +import org.eclipse.tm.rapi.ProcessInformation; import org.eclipse.tm.rapi.RapiException; import org.eclipse.tm.rapi.RapiFindData; @@ -249,7 +250,15 @@ public class RapiSession extends IRapiSession { throw new RapiException("CeGetFileTime failed", getError()); //$NON-NLS-1$ } return new Date((lwTime[0] / 10000) - OS.TIME_DIFF); - } + } + + public ProcessInformation createProcess(String appName, String commandLine, int creationFlags) throws RapiException { + ProcessInformation pi = new ProcessInformation(); + if (!CeCreateProcess(addr, appName, commandLine, creationFlags, pi)) { + throw new RapiException("CeCreateProcess failed", getError()); //$NON-NLS-1$ + } + return pi; + } public String toString() { return "[RapiSession] addr: " + Integer.toHexString(addr); //$NON-NLS-1$ @@ -307,4 +316,7 @@ public class RapiSession extends IRapiSession { private final native boolean CeGetFileTime(int addr, int hFile, long[] lpCreationTime, long[] lpLastAccessTime, long[] lpLastWriteTime); + + private final native boolean CeCreateProcess(int addr, String lpApplicationName, + String lpCommandLine, int dwCreationFlags, ProcessInformation lpProcessInformation); } diff --git a/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/rapi/IRapiSession.java b/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/rapi/IRapiSession.java index ee87c7c13ce..d9e13cd94a4 100644 --- a/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/rapi/IRapiSession.java +++ b/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/rapi/IRapiSession.java @@ -234,4 +234,14 @@ public abstract class IRapiSession extends IUnknown { */ public abstract Date getFileLastWriteTime(int handle) throws RapiException; + /** + * Creates new process on the remote device. + * @param appName module to execute + * @param commandLine command line arguments + * @param creationFlags additional flags controlling the creation + * @return ProcessInformaion containing information about the new process + * @throws RapiException if an error occurs. + */ + public abstract ProcessInformation createProcess(String appName, String commandLine, + int creationFlags) throws RapiException; } diff --git a/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/rapi/ProcessInformation.java b/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/rapi/ProcessInformation.java new file mode 100644 index 00000000000..361467000de --- /dev/null +++ b/wince/org.eclipse.tm.rapi/src/org/eclipse/tm/rapi/ProcessInformation.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2008 Radoslav Gerganov + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Radoslav Gerganov - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.rapi; + +/** + * This class contains information for a new process + * created with {@link IRapiSession#createProcess(String, String, int)} + * + * @author Radoslav Gerganov + */ +public class ProcessInformation { + public int hProcess; + public int hThread; + public int dwProcessId; + public int dwThreadId; +}