/******************************************************************************* | |
* Copyright (c) 2000, 2002 IBM Corporation and others. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Common Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/cpl-v10.html | |
* | |
* Contributors: | |
* IBM Corporation - initial API and implementation | |
*******************************************************************************/ | |
# include <update.h> | |
# include <windows.h> | |
# include <winioctl.h> // IOCTL codes: MediaType | |
// Windows Version | |
int WIN98 = 0; | |
int WINNT = 1; | |
int WINME = 2; | |
int WIN2000 = 3; | |
int WINXP = 4; | |
// set to 1 for DEBUG | |
int DEBUG = 0; | |
// set to 0 to run on Windows 95 *Unsupported* | |
int NOWIN95 = 1; | |
// GLOBAL METHODS | |
// --------------- | |
/* | |
* | |
*/ | |
jstring WindowsTojstring( JNIEnv* jnienv, char* buf ) | |
{ | |
jstring rtn = 0; | |
wchar_t* buffer = 0; | |
int bufferLen = strlen(buf); | |
if( bufferLen == 0 ){ | |
rtn = jnienv ->NewStringUTF(buf); | |
if (DEBUG) | |
printf("WindowsToJString Buffer is empty\n"); | |
} else { | |
int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)buf, bufferLen, NULL, 0 ); | |
buffer = (wchar_t*)malloc( length*2 + 1 ); | |
if(int err=MultiByteToWideChar( CP_ACP, 0, (LPCSTR)buf, bufferLen, (LPWSTR)buffer, length ) >0 ){ | |
rtn = jnienv->NewString((jchar*)buffer, length ); | |
} else { | |
if (DEBUG) | |
printf("MultiByteToWideChar %i\n",err); | |
} | |
} | |
if( buffer ) | |
free( buffer ); | |
return rtn; | |
} | |
/* | |
* calls GetVolumeInformation to retrive the label of the volume | |
* Returns NULL if an error occurs | |
* @param driveLetter path to the drive "c:\\" | |
* @prama jnienv JNIEnvironment | |
*/ | |
jstring getLabel(TCHAR driveLetter[],JNIEnv * jnienv){ | |
jstring result = NULL; | |
TCHAR buf[128]; | |
// always return null as UNICODE is not implemented | |
// how can we get the label of a volume as UNICODE char ? | |
return result; | |
int err = GetVolumeInformation( | |
driveLetter, | |
buf, | |
sizeof(buf) - 1, | |
NULL, | |
NULL, | |
NULL, | |
NULL, | |
0); | |
if (err){ | |
result = WindowsTojstring(jnienv, buf); | |
} else { | |
if (DEBUG) | |
printf("Error GetVolumeInformation %i\n",err); | |
} | |
return result; | |
} | |
/* | |
* returns the Version of Windows | |
* int 0 WIN98; | |
* int 1 WINNT; | |
* int 2 WINME; | |
* int 3 WIN2000; | |
* int 4 WINXP; | |
* returns -1 otherwise | |
*/ | |
int getWindowsVersion(){ | |
OSVERSIONINFOEX osvi; | |
int UNKNOWN = -1; | |
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); | |
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); | |
if(!(GetVersionEx((OSVERSIONINFO *)&osvi))){ | |
if (DEBUG) | |
printf("UNKNOWN VERSION: Cannot execute GetVersionEx\n"); | |
// if OSVERSIONEX doesn't work, try OSVERSIONINFO | |
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); | |
if(!(GetVersionEx((OSVERSIONINFO *)&osvi))){ | |
if (DEBUG) | |
printf("UNKNOWN VERSION: Cannot execute GetVersionEx\n"); | |
return UNKNOWN; | |
} | |
} | |
switch(osvi.dwPlatformId){ | |
case VER_PLATFORM_WIN32_NT: | |
if (DEBUG) | |
printf("VERSION NT: Maj %i Min %i\n",osvi.dwMajorVersion,osvi.dwMinorVersion); | |
if(osvi.dwMajorVersion<=4) | |
return WINNT; | |
if(osvi.dwMajorVersion==5){ | |
if (osvi.dwMinorVersion==0) | |
return WIN2000; | |
if (osvi.dwMinorVersion==1) | |
return WINXP; | |
} else { | |
return UNKNOWN; | |
}; | |
break; | |
case VER_PLATFORM_WIN32_WINDOWS: | |
if (DEBUG) | |
printf("VERSION Non NT: Maj %i Min %i\n",osvi.dwMajorVersion,osvi.dwMinorVersion); | |
if(osvi.dwMajorVersion==4){ | |
if (osvi.dwMinorVersion==10) | |
return WIN98; | |
if (osvi.dwMinorVersion==90) | |
return WINME; | |
} else { | |
return UNKNOWN; | |
} | |
break; | |
default: | |
if (DEBUG) | |
printf("VERSION UNKNOWN: Maj %i Min %i\n",osvi.dwMajorVersion,osvi.dwMinorVersion); | |
return UNKNOWN; | |
} | |
return UNKNOWN; | |
} | |
/* | |
* Returns the type of Removable Drive | |
* Returns | |
* org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_3 | |
* org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_5 | |
* org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOVABLE | |
*/ | |
jlong getFloppy(TCHAR driveLetter[]){ | |
TCHAR floppyPath[8]; | |
HANDLE handle; | |
DISK_GEOMETRY geometry[20]; | |
DWORD dw; | |
jlong UNKNOWN = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOVABLE; | |
sprintf(floppyPath, "\\\\.\\%c:", driveLetter[0]); | |
if (DEBUG) | |
printf("Path %s\n",floppyPath); | |
// BUG 25719 | |
SetErrorMode( SEM_FAILCRITICALERRORS ); | |
handle=CreateFile(floppyPath,0,FILE_SHARE_READ,NULL,OPEN_ALWAYS,0,NULL); | |
if (handle==INVALID_HANDLE_VALUE){ | |
if (DEBUG) | |
printf("Invalid Handle %s\n",floppyPath); | |
return UNKNOWN; | |
} else { | |
if(DeviceIoControl(handle, | |
IOCTL_DISK_GET_MEDIA_TYPES,0,0, | |
geometry,sizeof(geometry),&dw,0) | |
&& dw>0) { | |
switch(geometry[0].MediaType){ | |
case F5_160_512: | |
case F5_180_512: | |
case F5_320_512: | |
case F5_320_1024: | |
case F5_360_512: | |
case F5_1Pt2_512: | |
if (DEBUG) | |
printf("Found 5 1/4 Drive\n"); | |
return org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_5; | |
case F3_720_512: | |
case F3_1Pt44_512: | |
case F3_2Pt88_512: | |
case F3_20Pt8_512: | |
if (DEBUG) | |
printf("Found 3 1/2 Drive\n"); | |
return org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_3; | |
default: | |
return UNKNOWN; | |
} | |
} | |
} | |
return UNKNOWN; | |
} | |
/* | |
* Returns the UNC name of a remote drive | |
* (\\Machine\path\path1\path2$) | |
* returns NULL if an error occurs | |
*/ | |
jstring getRemoteNetworkName(TCHAR driveLetter[],JNIEnv * jnienv){ | |
unsigned long size =256; | |
TCHAR buf[256]; | |
TCHAR drivePath[2]; | |
DWORD err; | |
jstring result = NULL; | |
// always return NULL as UNICODE not implemented | |
// how can we get the label of a remote network name as UNICODE char ? | |
return result; | |
sprintf(drivePath, "%c:", driveLetter[0]); | |
err = WNetGetConnection(drivePath,buf,&size); | |
if (err==WN_SUCCESS){ | |
result = WindowsTojstring(jnienv,buf); | |
} else { | |
if (DEBUG) | |
printf("Error WNEtGetConnection %i",err); | |
} | |
return result; | |
} | |
// JNI METHODS | |
// --------------- | |
/* | |
* Class: org_eclipse_update_configuration_LocalSystemInfo | |
* Method: nativeGetFreeSpace | |
* Signature: (Ljava/io/File;)J | |
*/ | |
JNIEXPORT jlong JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetFreeSpace( | |
JNIEnv * jnienv, | |
jclass javaClass, | |
jobject file) { | |
// to retrive the String | |
jclass cls; | |
jmethodID id; | |
jobject obj; | |
// java.io.File.getAbsolutePath() | |
const TCHAR * lpDirectoryName; | |
// Windows Parameters | |
__int64 i64FreeBytesAvailableToCaller; | |
__int64 i64TotalNumberOfBytes; | |
__int64 i64TotalNumberOfFreeBytes; | |
// the result | |
jlong result = org_eclipse_update_configuration_LocalSystemInfo_SIZE_UNKNOWN; | |
// first, obtain the Path from the java.io.File parameter | |
cls = jnienv -> GetObjectClass(file); | |
id = jnienv -> GetMethodID(cls, "getAbsolutePath", "()Ljava/lang/String;"); | |
obj = jnienv -> CallObjectMethod(file, id); | |
lpDirectoryName = jnienv -> GetStringUTFChars((jstring) obj, 0); | |
if (DEBUG) | |
printf("Directory: [%s]\n",lpDirectoryName); | |
if (int win = (int)getWindowsVersion()<0 && NOWIN95){ | |
// windows 95 or other | |
if (DEBUG) | |
printf("Unsupported Windows: %i\n",win); | |
return result; | |
} | |
int err = GetDiskFreeSpaceEx( | |
lpDirectoryName, | |
(PULARGE_INTEGER) & i64FreeBytesAvailableToCaller, | |
(PULARGE_INTEGER) & i64TotalNumberOfBytes, | |
(PULARGE_INTEGER) & i64TotalNumberOfFreeBytes); | |
if (err) { | |
result = (jlong) i64FreeBytesAvailableToCaller; | |
} | |
return result; | |
} | |
/* | |
* Class: org_eclipse_update_configuration_LocalSystemInfo | |
* Method: nativeGetLabel | |
* Signature: (Ljava/io/File;)Ljava/lang/String; | |
*/ | |
JNIEXPORT jstring JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetLabel( | |
JNIEnv * jnienv, | |
jclass javaClass, | |
jobject file) { | |
// to retrive the String | |
jclass cls; | |
jmethodID id; | |
jobject obj; | |
// java.io.File.getAbsolutePath() | |
const TCHAR * lpDirectoryName; | |
// obtain the String from the parameter | |
cls = jnienv -> GetObjectClass(file); | |
id = jnienv -> GetMethodID(cls, "getAbsolutePath", "()Ljava/lang/String;"); | |
obj = jnienv -> CallObjectMethod(file, id); | |
lpDirectoryName = jnienv -> GetStringUTFChars((jstring) obj, 0); | |
if (DEBUG) | |
printf("Directory: [%s]\n",lpDirectoryName); | |
// | |
jstring result = NULL; | |
int floppy; | |
if (int win = (int)getWindowsVersion()<0 && NOWIN95){ | |
// windows 95 or other | |
if (DEBUG) | |
printf("Unsupported Windows: %i\n",win); | |
return result; | |
} | |
// Make sure we have a String of the Form: <letter>: | |
if (':' == lpDirectoryName[1]) { | |
TCHAR driveLetter[4]; // i.e. -> C:\\ | |
memcpy(driveLetter, lpDirectoryName, 2); | |
strcpy(driveLetter + 2, "\\"); | |
switch (GetDriveType(driveLetter)) { | |
case DRIVE_REMOTE : | |
// check name of machine and path of remote | |
if (DEBUG) | |
printf("Remote Drive"); | |
result = getRemoteNetworkName(driveLetter,jnienv); | |
break; | |
default : | |
if (DEBUG) | |
printf("Another Drive at %s", driveLetter); | |
result = getLabel(driveLetter,jnienv); | |
break; | |
} | |
} | |
return result; | |
} | |
/* | |
* Class: org_eclipse_update_configuration_LocalSystemInfo | |
* Method: nativeGetType | |
* Signature: (Ljava/io/File;)I | |
*/ | |
JNIEXPORT jint JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetType( | |
JNIEnv * jnienv, | |
jclass javaClass, | |
jobject file) { | |
// to retrive the String | |
jclass cls; | |
jmethodID id; | |
jobject obj; | |
// java.io.File.getAbsolutePath() | |
const TCHAR * lpDirectoryName; | |
// obtain the String from the parameter | |
cls = jnienv -> GetObjectClass(file); | |
id = jnienv -> GetMethodID(cls, "getAbsolutePath", "()Ljava/lang/String;"); | |
obj = jnienv -> CallObjectMethod(file, id); | |
lpDirectoryName = jnienv -> GetStringUTFChars((jstring) obj, 0); | |
if (DEBUG) | |
printf("Directory: [%s]\n",lpDirectoryName); | |
int result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_UNKNOWN; | |
if (int win = (int)getWindowsVersion()<0 && NOWIN95){ | |
// windows 95 or other | |
if (DEBUG) | |
printf("Unsupported Windows: %i\n",win); | |
return result; | |
} | |
// Make sure we have a String of the Form: <letter>: | |
if (':' == lpDirectoryName[1]) { | |
TCHAR driveLetter[4]; //C:\\ | |
memcpy(driveLetter, lpDirectoryName, 2); | |
strcpy(driveLetter + 2, "\\"); | |
switch (GetDriveType(driveLetter)) { | |
case DRIVE_REMOVABLE : | |
// check if floppy 3.5, floppy 5.25 | |
// or other removable device (USB,PCMCIA ...) | |
if (DEBUG) | |
printf("Removable Device"); | |
result = getFloppy(driveLetter); | |
break; | |
case DRIVE_CDROM : | |
result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_CDROM; | |
break; | |
case DRIVE_FIXED : | |
result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FIXED; | |
break; | |
case DRIVE_REMOTE : | |
result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOTE; | |
break; | |
case DRIVE_NO_ROOT_DIR : | |
result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_INVALID_PATH; | |
break; | |
case DRIVE_RAMDISK : | |
result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_RAMDISK; | |
break; | |
case DRIVE_UNKNOWN : | |
default : | |
result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_UNKNOWN; | |
break; | |
} | |
} else { | |
result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_INVALID_PATH; | |
} | |
return result; | |
} | |
/* | |
* Class: org_eclipse_update_configuration_LocalSystemInfo | |
* Method: nativeListMountPoints | |
* Signature: ()[Ljava/lang/String; | |
*/ | |
JNIEXPORT jobjectArray JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeListMountPoints( | |
JNIEnv * jnienv, | |
jclass javaClass) { | |
// | |
DWORD logDrives; | |
UINT drive; | |
TCHAR driveName[100]; | |
jobjectArray returnArray; | |
int nDrive = 0; | |
// | |
jclass stringClass; | |
jobject empty; | |
int index = 0; | |
jobject str; | |
logDrives = GetLogicalDrives(); | |
for (drive = 0; drive < 32; drive++) { | |
if (logDrives & (1 << drive)) { | |
nDrive++; | |
} | |
} | |
stringClass = jnienv -> FindClass("java/lang/String"); | |
empty = jnienv -> NewStringUTF(""); | |
returnArray = jnienv -> NewObjectArray(nDrive, stringClass, empty); | |
if (int win = (int)getWindowsVersion()<0 && NOWIN95){ | |
// windows 95 or other | |
if (DEBUG) | |
printf("Unsupported Windows: %i\n",win); | |
return NULL; | |
} | |
for (drive = 0; drive < 32; drive++) { | |
if (logDrives & (1 << drive)) { | |
sprintf(driveName, "%c:\\", drive + 'A'); | |
str = jnienv -> NewStringUTF(driveName); | |
jnienv -> SetObjectArrayElement(returnArray, index, str); | |
index++; | |
} | |
} | |
return returnArray; | |
} | |