Skip to content

Commit

Permalink
Remove unused (native) code in Windows LocalFileNatives
Browse files Browse the repository at this point in the history
Unicode support was assumed to be present if the Windows-OS version is
greater or equal five, which corresponds to Windows 2000 or later [1].
Because parts of the removed and remaining native code call methods that
are only available on Windows XP/Server 2003 or later, for example
'FindFirstFileA()' (the code says 'FindFirstFile' but it is linked to
'FindFirstFileA') respectively 'FindFirstFileW()', it is save to assume
Unicode is always supported. All methods that check it or handle an
alternative encoding are effectively dead code and can be removed.

Furthermore only 64-bit artifacts are provided now and 64-bit CPU are
not supported before Windows XP, too.

Also remove build-scripts for CPU architectures not supported anymore
and java and native code that is not called (anymore).

[1] - https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfow
  • Loading branch information
HannesWell committed Jun 12, 2024
1 parent ad89d5c commit 7ff7a58
Show file tree
Hide file tree
Showing 8 changed files with 16 additions and 490 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2012 IBM Corporation and others.
* Copyright (c) 2000, 2024 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -51,22 +51,6 @@ extern "C" {
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_nativeAttributes
(JNIEnv *, jclass);

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalIsUnicode
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalIsUnicode
(JNIEnv *, jclass);

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalGetFileInfo
* Signature: ([CLorg/eclipse/core/filesystem/IFileInfo;)Z
*/
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalGetFileInfo
(JNIEnv *env, jclass clazz, jbyteArray target, jobject fileInfo);

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalGetFileInfoW
Expand All @@ -75,30 +59,6 @@ JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_Local
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalGetFileInfoW
(JNIEnv *env, jclass clazz, jcharArray target, jobject fileInfo);

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalCopyAttributes
* Signature: ([B[BZ)Z
*/
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalCopyAttributes
(JNIEnv *env, jclass clazz, jbyteArray source, jbyteArray destination, jboolean copyLastModified);

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalCopyAttributesW
* Signature: ([C[CZ)Z
*/
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalCopyAttributesW
(JNIEnv *env, jclass clazz, jcharArray source, jcharArray destination, jboolean copyLastModified);

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalSetFileInfo
* Signature: ([BLorg/eclipse/core/filesystem/IFileInfo;)Z
*/
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalSetFileInfo
(JNIEnv *env, jclass clazz, jcharArray target, jobject obj);

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalSetFileInfoW
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,6 @@ jlong fileTimeToMillis(FILETIME ft) {
return millis;
}

/*
* Get a null-terminated byte array from a java byte array.
* The returned bytearray needs to be freed when not used
* anymore. Use free(result) to do that.
*/
jbyte* getByteArray(JNIEnv *env, jbyteArray target) {
jsize n;
jbyte *temp, *result;

temp = (*env)->GetByteArrayElements(env, target, 0);
n = (*env)->GetArrayLength(env, target);
result = malloc((n+1) * sizeof(jbyte));
memcpy(result, temp, n * sizeof(jbyte));
result[n] = '\0';
(*env)->ReleaseByteArrayElements(env, target, temp, 0);
return result;
}

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: nativeAttributes
Expand All @@ -104,24 +86,6 @@ JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFile
return attributes;
}

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalIsUnicode
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalIsUnicode
(JNIEnv *env, jclass clazz) {
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx (&osvi))
return JNI_FALSE;
// only Windows NT 4, Windows 2K and XP support Unicode API calls
if (!(osvi.dwMajorVersion >= 5 || (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion == 4)))
return JNI_FALSE;
return JNI_TRUE;
}

/*
* Get a null-terminated short array from a java char array.
* The returned short array needs to be freed when not used
Expand All @@ -140,93 +104,6 @@ jchar* getCharArray(JNIEnv *env, jcharArray target) {
return result;
}

/*
* Returns a Java string object for a given windows character string
*/
jstring windowsTojstring( JNIEnv* env, char* str )
{
jstring rtn = 0;
int slen = strlen(str);
wchar_t* buffer = 0;
if( slen == 0 )
rtn = (*env)->NewStringUTF( env, str ); //UTF ok since empty string
else
{
int length =
MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
buffer = malloc( length*2 + 1 );
if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen,
(LPWSTR)buffer, length ) >0 )
rtn = (*env)->NewString( env, (jchar*)buffer, length );
}
if( buffer )
free( buffer );
return rtn;
}

/*
* Converts a WIN32_FIND_DATA to IFileInfo
*/
jboolean convertFindDataToFileInfo(JNIEnv *env, WIN32_FIND_DATA info, jobject fileInfo) {
jclass cls;
jmethodID mid;
ULONGLONG fileLength;

cls = (*env)->GetObjectClass(env, fileInfo);
if (cls == 0) return JNI_FALSE;

// select interesting information
//exists
mid = (*env)->GetMethodID(env, cls, "setExists", "(Z)V");
if (mid == 0) return JNI_FALSE;
(*env)->CallVoidMethod(env, fileInfo, mid, JNI_TRUE);

// file name
mid = (*env)->GetMethodID(env, cls, "setName", "(Ljava/lang/String;)V");
if (mid == 0) return JNI_FALSE;
(*env)->CallVoidMethod(env, fileInfo, mid, windowsTojstring(env, info.cFileName));

// last modified
mid = (*env)->GetMethodID(env, cls, "setLastModified", "(J)V");
if (mid == 0) return JNI_FALSE;
(*env)->CallVoidMethod(env, fileInfo, mid, fileTimeToMillis(info.ftLastWriteTime));

// file length
fileLength =(info.nFileSizeHigh * (((ULONGLONG)MAXDWORD)+1)) + info.nFileSizeLow;
mid = (*env)->GetMethodID(env, cls, "setLength", "(J)V");
if (mid == 0) return JNI_FALSE;
(*env)->CallVoidMethod(env, fileInfo, mid, fileLength);

// folder or file?
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
if (mid == 0) return JNI_FALSE;
(*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_DIRECTORY, JNI_TRUE);
}

// read-only?
if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
if (mid == 0) return JNI_FALSE;
(*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_READ_ONLY, JNI_TRUE);
}

// archive?
if (info.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {
mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
if (mid == 0) return JNI_FALSE;
(*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_ARCHIVE, JNI_TRUE);
}

// hidden?
if (info.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
if (mid == 0) return JNI_FALSE;
(*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_HIDDEN, JNI_TRUE);
}
return JNI_TRUE;
}

/*
* Set symbolic link information in IFileInfo
*/
Expand Down Expand Up @@ -398,38 +275,6 @@ jboolean setIOError(JNIEnv *env, jobject fileInfo) {
return JNI_TRUE;
}

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalGetFileInfo
* Signature: ([CLorg/eclipse/core/filesystem/IFileInfo;)Z
*/
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalGetFileInfo
(JNIEnv *env, jclass clazz, jbyteArray target, jobject fileInfo) {
jbyte *name;
jsize size;
HANDLE handle;
WIN32_FIND_DATA info;

name = getByteArray(env, target);
size = (*env)->GetArrayLength(env, target);
// FindFirstFile does not work at the root level. However, we
// don't need it because the root will never change timestamp
// The pattern \\?\c:\ represents a root path
if (size == 7 && name[2] == '?' && name[5] == ':' && name[6] == '\\') {
free(name);
return fillEmptyDirectory(env, fileInfo);
}
handle = FindFirstFile(name, &info);
free(name);
if (handle == INVALID_HANDLE_VALUE) {
if (GetLastError() != ERROR_FILE_NOT_FOUND)
setIOError(env, fileInfo);
return JNI_FALSE;
}
FindClose(handle);
return convertFindDataToFileInfo(env, info, fileInfo);
}

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalGetFileInfoW
Expand Down Expand Up @@ -466,127 +311,6 @@ JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_Local
return result;
}

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalCopyAttributes
* Signature: ([B[BZ)Z
*/
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalCopyAttributes
(JNIEnv *env, jclass clazz, jbyteArray source, jbyteArray destination, jboolean copyLastModified) {

HANDLE handle;
WIN32_FIND_DATA info;
jbyte *sourceFile, *destinationFile;
int success = 1;

sourceFile = getByteArray(env, source);
destinationFile = getByteArray(env, destination);

handle = FindFirstFile(sourceFile, &info);
if (handle != INVALID_HANDLE_VALUE) {
success = SetFileAttributes(destinationFile, info.dwFileAttributes);
if (success != 0 && copyLastModified) {
// does not honor copyLastModified
// call to SetFileTime should pass file handle instead of file name
// success = SetFileTime(destinationFile, &info.ftCreationTime, &info.ftLastAccessTime, &info.ftLastWriteTime);
}
} else {
success = 0;
}

free(sourceFile);
free(destinationFile);
FindClose(handle);
return success;
}

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalCopyAttributesW
* Signature: ([C[CZ)Z
*/
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalCopyAttributesW
(JNIEnv *env, jclass clazz, jcharArray source, jcharArray destination, jboolean copyLastModified) {

HANDLE handle;
WIN32_FIND_DATAW info;
jchar *sourceFile, *destinationFile;
int success = 1;

sourceFile = getCharArray(env, source);
destinationFile = getCharArray(env, destination);

handle = FindFirstFileW(sourceFile, &info);

if (handle != INVALID_HANDLE_VALUE) {
success = SetFileAttributesW(destinationFile, info.dwFileAttributes);
if (success != 0 && copyLastModified) {
// does not honor copyLastModified
// call to SetFileTime should pass file handle instead of file name
// success = SetFileTime(destinationFile, &info.ftCreationTime, &info.ftLastAccessTime, &info.ftLastWriteTime);
}
} else {
success = 0;
}

free(sourceFile);
free(destinationFile);
FindClose(handle);
return success;
}

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalSetFileInfo
* Signature: ([BLorg/eclipse/core/filesystem/IFileInfo;)Z
*/
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalSetFileInfo
(JNIEnv *env, jclass clazz, jcharArray target, jobject obj) {

HANDLE handle;
jbyte *targetFile;
jmethodID mid;
int success = JNI_FALSE;
DWORD attributes;
jboolean readOnly, hidden, archive;
jclass cls;

/* find out if we need to set the readonly bit */
cls = (*env)->GetObjectClass(env, obj);
mid = (*env)->GetMethodID(env, cls, "getAttribute", "(I)Z");
if (mid == 0) goto fail;
readOnly = (*env)->CallBooleanMethod(env, obj, mid, ATTRIBUTE_READ_ONLY);

/* find out if we need to set the archive bit */
archive = (*env)->CallBooleanMethod(env, obj, mid, ATTRIBUTE_ARCHIVE);

/* find out if we need to set the hidden bit */
hidden = (*env)->CallBooleanMethod(env, obj, mid, ATTRIBUTE_HIDDEN);

targetFile = getByteArray(env, target);
attributes = GetFileAttributes(targetFile);
if (attributes == (DWORD)-1) goto fail;

if (readOnly)
attributes = attributes | FILE_ATTRIBUTE_READONLY;
else
attributes = attributes & ~FILE_ATTRIBUTE_READONLY;
if (archive)
attributes = attributes | FILE_ATTRIBUTE_ARCHIVE;
else
attributes = attributes & ~FILE_ATTRIBUTE_ARCHIVE;
if (hidden)
attributes = attributes | FILE_ATTRIBUTE_HIDDEN;
else
attributes = attributes & ~FILE_ATTRIBUTE_HIDDEN;

success = SetFileAttributes(targetFile, attributes);

fail:
free(targetFile);
return success;
}

/*
* Class: org_eclipse_core_internal_filesystem_local_LocalFileNatives
* Method: internalSetFileInfoW
Expand Down
Loading

0 comments on commit 7ff7a58

Please sign in to comment.