diff --git a/wince/org.eclipse.tm.rapi.tests/src/org/eclipse/tm/rapi/tests/RapiSessionTest.java b/wince/org.eclipse.tm.rapi.tests/src/org/eclipse/tm/rapi/tests/RapiSessionTest.java
index b7d1e8089e7..7a27ebcb0ca 100644
--- a/wince/org.eclipse.tm.rapi.tests/src/org/eclipse/tm/rapi/tests/RapiSessionTest.java
+++ b/wince/org.eclipse.tm.rapi.tests/src/org/eclipse/tm/rapi/tests/RapiSessionTest.java
@@ -141,9 +141,19 @@ public class RapiSessionTest extends RapiTestCase {
// ignore
}
session.createDirectory(TEST_DIR_NAME);
- assertTrue("Failed to create directory", isDirectory(TEST_DIR_NAME));
+ assertTrue("Failed to create directory: " + TEST_DIR_NAME, isDirectory(TEST_DIR_NAME));
session.removeDirectory(TEST_DIR_NAME);
- assertFalse("Failed to remove directory", isDirectory(TEST_DIR_NAME));
+ assertFalse("Failed to remove directory: " + TEST_DIR_NAME, isDirectory(TEST_DIR_NAME));
+ }
+
+ /**
+ * Utility method for creating files.
+ */
+ void createFile(IRapiSession session, String fileName) throws RapiException {
+ int handle = session.createFile(fileName, OS.GENERIC_WRITE,
+ OS.FILE_SHARE_READ, OS.CREATE_ALWAYS, OS.FILE_ATTRIBUTE_NORMAL);
+ session.writeFile(handle, "spam".getBytes());
+ session.closeHandle(handle);
}
/**
@@ -153,24 +163,23 @@ public class RapiSessionTest extends RapiTestCase {
createInitSession();
// create test file
- int handle = session.createFile(TEST_FILE_NAME, OS.GENERIC_WRITE,
- OS.FILE_SHARE_READ, OS.CREATE_ALWAYS, OS.FILE_ATTRIBUTE_NORMAL);
- session.writeFile(handle, "spam".getBytes());
- session.closeHandle(handle);
+ createFile(session, TEST_FILE_NAME);
// make a copy
String copy = TEST_FILE_NAME + "1";
session.copyFile(TEST_FILE_NAME, copy);
- assertTrue("Failed to copy file", isFile(copy));
+ assertTrue("The copied file doesn't exist: " + copy, isFile(copy));
// delete the test file
session.deleteFile(TEST_FILE_NAME);
- assertFalse("Failed to delete file", isFile(TEST_FILE_NAME));
+ assertFalse("Failed to delete file: " + TEST_FILE_NAME, isFile(TEST_FILE_NAME));
// rename the copy
session.moveFile(copy, TEST_FILE_NAME);
- assertTrue("Failed to move file", isFile(TEST_FILE_NAME));
- assertFalse("Failed to move file", isFile(copy));
+ assertTrue("Failed to move file, existing file: " + copy + " new file: " + TEST_FILE_NAME,
+ isFile(TEST_FILE_NAME));
+ assertFalse("Failed to move file, existing file: " + copy + " new file: " + TEST_FILE_NAME,
+ isFile(copy));
// delete test file
session.deleteFile(TEST_FILE_NAME);
@@ -181,10 +190,7 @@ public class RapiSessionTest extends RapiTestCase {
*/
void createTempFiles() throws RapiException {
for (int i = 0 ; i < TEMP_FILES_COUNT ; i++) {
- int handle = session.createFile(TEST_FILE_NAME + i, OS.GENERIC_WRITE,
- OS.FILE_SHARE_READ, OS.CREATE_ALWAYS, OS.FILE_ATTRIBUTE_NORMAL);
- session.writeFile(handle, "spam".getBytes());
- session.closeHandle(handle);
+ createFile(session, TEST_FILE_NAME + i);
}
}
@@ -227,19 +233,66 @@ public class RapiSessionTest extends RapiTestCase {
}
/**
- * Tests getting file attributes, size, etc.
+ * Tests getting and setting file attributes
*/
- public void testStatFiles() throws RapiException {
+ public void testGetSetFileAttributes() throws RapiException {
createInitSession();
// create test file
- int handle = session.createFile(TEST_FILE_NAME, OS.GENERIC_WRITE,
+ createFile(session, TEST_FILE_NAME);
+
+ session.setFileAttributes(TEST_FILE_NAME, OS.FILE_ATTRIBUTE_READONLY);
+ int attr = session.getFileAttributes(TEST_FILE_NAME);
+ assertTrue("Wrong file attributes, expected FILE_ATTRIBUTE_READONLY",
+ (attr & OS.FILE_ATTRIBUTE_READONLY) != 0);
+
+ session.setFileAttributes(TEST_FILE_NAME, OS.FILE_ATTRIBUTE_ARCHIVE);
+ attr = session.getFileAttributes(TEST_FILE_NAME);
+ assertTrue("Wrong file attributes, expected FILE_ATTRIBUTE_ARCHIVE",
+ (attr & OS.FILE_ATTRIBUTE_ARCHIVE) != 0);
+
+ //clean up
+ session.deleteFile(TEST_FILE_NAME);
+ }
+
+ /**
+ * Tests getting file size using {@link IRapiSession#getFileSize(int)}
+ */
+ public void testGetFileSize() throws RapiException {
+ createInitSession();
+ // create test file
+ int handle = session.createFile(TEST_FILE_NAME, OS.GENERIC_WRITE,
OS.FILE_SHARE_READ, OS.CREATE_ALWAYS, OS.FILE_ATTRIBUTE_NORMAL);
session.writeFile(handle, "spam".getBytes());
- assertTrue("Wrong file size", 4 == session.getFileSize(handle));
- //TODO: add some checks for file times (creation, last modified, etc)
+ assertTrue("Wrong file size, expected size 4 bytes", 4 == session.getFileSize(handle));
session.closeHandle(handle);
- int attr = session.getFileAttributes(TEST_FILE_NAME);
- assertTrue("Wrong file attributes", (attr & OS.FILE_ATTRIBUTE_ARCHIVE) != 0);
+ //clean up
+ session.deleteFile(TEST_FILE_NAME);
+ }
+
+ /**
+ * Tests getting and setting file times
+ */
+ public void testGetSetFileTime() throws RapiException {
+ createInitSession();
+
+ // now + 1h
+ long d = System.currentTimeMillis() + 3600000;
+
+ // create file and set last access time to d
+ int handle = session.createFile(TEST_FILE_NAME, OS.GENERIC_WRITE,
+ OS.FILE_SHARE_READ, OS.CREATE_ALWAYS, OS.FILE_ATTRIBUTE_NORMAL);
+ session.writeFile(handle, "spam".getBytes());
+ session.setFileLastWriteTime(handle, d);
+ session.closeHandle(handle);
+ // get file last write time and compare to d
+ handle = session.createFile(TEST_FILE_NAME, OS.GENERIC_READ,
+ OS.FILE_SHARE_READ, OS.OPEN_EXISTING, OS.FILE_ATTRIBUTE_NORMAL);
+ long lwTime = session.getFileLastWriteTime(handle);
+ // the precision of setLastWriteTime should be about 1-2sec
+ assertTrue("Too big difference for lastWriteTime, expected: " + d
+ + " returned: " + lwTime, Math.abs(lwTime - d) <= 5000);
+ session.closeHandle(handle);
+
//clean up
session.deleteFile(TEST_FILE_NAME);
}
diff --git a/wince/org.eclipse.tm.rapi/native/RapiSession.cpp b/wince/org.eclipse.tm.rapi/native/RapiSession.cpp
index 350892f17df..21237b69fa7 100644
--- a/wince/org.eclipse.tm.rapi/native/RapiSession.cpp
+++ b/wince/org.eclipse.tm.rapi/native/RapiSession.cpp
@@ -258,6 +258,14 @@ jlong FILETIME2jlong(FILETIME ft)
return res;
}
+LPFILETIME jlong2FILETIME(jlong jl, LPFILETIME ft)
+{
+ ft->dwLowDateTime = (DWORD)jl;
+ jl >>= 32;
+ ft->dwHighDateTime = (DWORD)jl;
+ return ft;
+}
+
void setFIND_DATAFields(JNIEnv *env, jobject lpObject, CE_FIND_DATA *pFindData)
{
if (!FIND_DATAFc.cached) cacheFIND_DATAFields(env, lpObject);
@@ -437,6 +445,58 @@ fail:
return rc;
}
+JNIEXPORT jboolean JNICALL RAPI_NATIVE(CeSetFileAttributes)
+ (JNIEnv *env, jobject that, jint arg0, jstring arg1, jint arg2)
+{
+ jboolean rc = 0;
+ const jchar *lparg1 = NULL;
+
+ if (arg0 == 0) return rc;
+ if (arg1) {
+ lparg1 = env->GetStringChars(arg1, NULL);
+ if (lparg1 == NULL) goto fail;
+ }
+ IRAPISession *pSession = (IRAPISession*) arg0;
+ rc = pSession->CeSetFileAttributes((LPCWSTR)lparg1, arg2);
+fail:
+ if (arg1 && lparg1) env->ReleaseStringChars(arg1, lparg1);
+ return rc;
+}
+
+JNIEXPORT jboolean JNICALL RAPI_NATIVE(CeSetFileTime)
+ (JNIEnv *env, jobject that, jint arg0, jint arg1, jlongArray arg2, jlongArray arg3, jlongArray arg4)
+{
+ jboolean rc = 0;
+ FILETIME crTime, laTime, lwTime;
+ LPFILETIME pcrTime = NULL, plaTime = NULL, plwTime = NULL;
+ jlong *lparg2 = NULL, *lparg3 = NULL, *lparg4 = NULL;
+
+ if (arg0 == 0) return 0;
+ if (arg2) {
+ lparg2 = env->GetLongArrayElements(arg2, NULL);
+ if (lparg2 == NULL) goto fail;
+ pcrTime = jlong2FILETIME(lparg2[0], &crTime);
+ }
+ if (arg3) {
+ lparg3 = env->GetLongArrayElements(arg3, NULL);
+ if (lparg3 == NULL) goto fail;
+ plaTime = jlong2FILETIME(lparg3[0], &laTime);
+ }
+ if (arg4) {
+ lparg4 = env->GetLongArrayElements(arg4, NULL);
+ if (lparg4 == NULL) goto fail;
+ plwTime = jlong2FILETIME(lparg4[0], &lwTime);
+ }
+
+ IRAPISession *pSession = (IRAPISession*) arg0;
+ rc = pSession->CeSetFileTime((HANDLE)arg1, pcrTime, plaTime, plwTime);
+fail:
+ if (arg2 && lparg2) env->ReleaseLongArrayElements(arg2, lparg2, 0);
+ 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;
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 75dd9bdaec8..115fc6346b1 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
@@ -185,6 +185,22 @@ 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: CeSetFileAttributes
+ * Signature: (ILjava/lang/String;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_eclipse_tm_internal_rapi_RapiSession_CeSetFileAttributes
+ (JNIEnv *, jobject, jint, jstring, jint);
+
+/*
+ * Class: org_eclipse_tm_internal_rapi_RapiSession
+ * Method: CeSetFileTime
+ * Signature: (II[J[J[J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_eclipse_tm_internal_rapi_RapiSession_CeSetFileTime
+ (JNIEnv *, jobject, jint, jint, jlongArray, jlongArray, jlongArray);
+
/*
* Class: org_eclipse_tm_internal_rapi_RapiSession
* Method: CeCreateProcess
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 bb5074f1513..8f69a14052f 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
@@ -10,8 +10,6 @@
*******************************************************************************/
package org.eclipse.tm.internal.rapi;
-import java.util.Date;
-
import org.eclipse.tm.rapi.IRapiSession;
import org.eclipse.tm.rapi.OS;
import org.eclipse.tm.rapi.ProcessInformation;
@@ -219,7 +217,7 @@ public class RapiSession extends IRapiSession {
return ( ((long)sizeHigh[0] << 32) | (sizeLow & 0xFFFFFFFF));
}
- public Date getFileCreationTime(int handle) throws RapiException {
+ public long getFileCreationTime(int handle) throws RapiException {
long[] crTime = new long[1];
long[] laTime = new long[1];
long[] lwTime = new long[1];
@@ -227,10 +225,10 @@ public class RapiSession extends IRapiSession {
if (!res) {
throw new RapiException("CeGetFileTime failed", getError()); //$NON-NLS-1$
}
- return new Date((crTime[0] / 10000) - OS.TIME_DIFF);
+ return (crTime[0] / 10000) - OS.TIME_DIFF;
}
- public Date getFileLastAccessTime(int handle) throws RapiException {
+ public long getFileLastAccessTime(int handle) throws RapiException {
long[] crTime = new long[1];
long[] laTime = new long[1];
long[] lwTime = new long[1];
@@ -238,10 +236,10 @@ public class RapiSession extends IRapiSession {
if (!res) {
throw new RapiException("CeGetFileTime failed", getError()); //$NON-NLS-1$
}
- return new Date((laTime[0] / 10000) - OS.TIME_DIFF);
+ return (laTime[0] / 10000) - OS.TIME_DIFF;
}
- public Date getFileLastWriteTime(int handle) throws RapiException {
+ public long getFileLastWriteTime(int handle) throws RapiException {
long[] crTime = new long[1];
long[] laTime = new long[1];
long[] lwTime = new long[1];
@@ -249,7 +247,25 @@ public class RapiSession extends IRapiSession {
if (!res) {
throw new RapiException("CeGetFileTime failed", getError()); //$NON-NLS-1$
}
- return new Date((lwTime[0] / 10000) - OS.TIME_DIFF);
+ return (lwTime[0] / 10000) - OS.TIME_DIFF;
+ }
+
+ public void setFileAttributes(String fileName, int fileAttributes) throws RapiException {
+ boolean res = CeSetFileAttributes(addr, fileName, fileAttributes);
+ if (!res) {
+ throw new RapiException("CeSetFileAttributes failed", getError()); //$NON-NLS-1$
+ }
+ }
+
+ public void setFileLastWriteTime(int handle, long lastWriteTime) throws RapiException {
+ if (lastWriteTime < 0) {
+ throw new IllegalArgumentException("Time cannot be negative"); //$NON-NLS-1$
+ }
+ long[] lwTime = new long[] {(lastWriteTime + OS.TIME_DIFF) * 10000};
+ boolean res = CeSetFileTime(addr, handle, null, null, lwTime);
+ if (!res) {
+ throw new RapiException("CeSetFileTime failed", getError()); //$NON-NLS-1$
+ }
}
public ProcessInformation createProcess(String appName, String commandLine, int creationFlags) throws RapiException {
@@ -317,6 +333,11 @@ public class RapiSession extends IRapiSession {
private final native boolean CeGetFileTime(int addr, int hFile,
long[] lpCreationTime, long[] lpLastAccessTime, long[] lpLastWriteTime);
+ private final native boolean CeSetFileAttributes(int addr, String lpFileName, int dwFileAttributes);
+
+ private final native boolean CeSetFileTime(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 d9e13cd94a4..a86d79fa231 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
@@ -10,8 +10,6 @@
*******************************************************************************/
package org.eclipse.tm.rapi;
-import java.util.Date;
-
/**
* This class is used to perform Remote API 2 operations on a connected
* WinCE-based remote device.
@@ -208,32 +206,66 @@ public abstract class IRapiSession extends IUnknown {
public abstract long getFileSize(int handle);
/**
- * Returns when the file was created.
- * @param handle handle to the file for which to get dates and times
- * @return Date
object representing the date and time when
- * the file was created
+ * Returns the time when the file was created.
+ *
+ * The time is represented as the number of Universal Time (UT) + * milliseconds since the epoch (00:00:00 GMT, January 1, 1970). + *
+ * @param handle handle to the file for which to get creation time + * @return the creation time for this file * @throws RapiException if an error occurs. */ - public abstract Date getFileCreationTime(int handle) throws RapiException; + public abstract long getFileCreationTime(int handle) throws RapiException; /** - * Returns when the file was last accessed. - * @param handle handle to the file for which to get dates and times - * @returnDate
object representing the date and time when
- * the file was last accessed
+ * Returns the time when the file was last accessed.
+ * + * The time is represented as the number of Universal Time (UT) + * milliseconds since the epoch (00:00:00 GMT, January 1, 1970). + *
+ * @param handle handle to the file for which to get last access time + * @return the last access time for this file * @throws RapiException if an error occurs. */ - public abstract Date getFileLastAccessTime(int handle) throws RapiException; + public abstract long getFileLastAccessTime(int handle) throws RapiException; /** - * Returns when the file was last written to. - * @param handle handle to the file for which to get dates and times - * @returnDate
object representing the date and time when
- * the file was last written to
+ * Returns the time when the file was last written to.
+ * + * The time is represented as the number of Universal Time (UT) + * milliseconds since the epoch (00:00:00 GMT, January 1, 1970). + *
+ * @param handle handle to the file for which to get last write time + * @return the last write time for this file * @throws RapiException if an error occurs. */ - public abstract Date getFileLastWriteTime(int handle) throws RapiException; + public abstract long getFileLastWriteTime(int handle) throws RapiException; + /** + * Sets the attributes of the specified file on the remote device. + * @param fileName the target file + * @param fileAttributes the new attributes; this parameter is combination of the + * following values: {@link OS#FILE_ATTRIBUTE_ARCHIVE}, {@link OS#FILE_ATTRIBUTE_HIDDEN}, + * {@link OS#FILE_ATTRIBUTE_NORMAL}, {@link OS#FILE_ATTRIBUTE_READONLY}, + * {@link OS#FILE_ATTRIBUTE_SYSTEM}, {@link OS#FILE_ATTRIBUTE_TEMPORARY} + * @throws RapiException if an error occurs. + */ + public abstract void setFileAttributes(String fileName, int fileAttributes) throws RapiException; + + /** + * Sets the last write time of the specified file. + *+ * The time is represented as the number of Universal Time (UT) + * milliseconds since the epoch (00:00:00 GMT, January 1, 1970). + *
+ * The specified time will be truncated to fit the supported precision. + * @param handle handle to the target file + * @param lastWriteTime the new last write time for this file + * @throws IllegalArgumentException if the specified time is negative + * @throws RapiException if an error occurs. + */ + public abstract void setFileLastWriteTime(int handle, long lastWriteTime) throws RapiException; + /** * Creates new process on the remote device. * @param appName module to execute