JUDGER_AND_CLIENT/Lib/registry-3.1.3/source/windows/RegistryKey.c

2087 lines
41 KiB
C
Raw Normal View History

2024-01-12 20:48:35 +08:00
/*
** Java native interface to the Windows Registry API.
**
** Authored by Timothy Gerard Endres
** <mailto:time@gjt.org> <http://www.trustice.com>
**
** This work has been placed into the public domain.
** You may use this work in any way and for any purpose you wish.
**
** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
** REDISTRIBUTION OF THIS SOFTWARE.
**
** Release 3.1.3
**
*/
#include "RegistryKey.h"
#include <wtypes.h>
#include <winbase.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include "RegistryKeyProto.h"
JNIEXPORT jobject JNICALL
Java_com_ice_jni_registry_RegistryKey_connectRegistry
( JNIEnv *env, jobject rkObject, jstring jHostName )
{
LONG regErr;
HKEY hKey;
HKEY remoteKey;
jstring jKeyName;
char *hostName;
jobject result = NULL;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return NULL;
jKeyName = getRegistryKeyName( env, rkObject );
if ( isThrowing( env ) )
return NULL;
hostName = jStringToNewAscii( env, jHostName );
if ( hostName == NULL )
{
throwOutOfMemoryError( env, "jStringToNewAscii(hostName)" );
return NULL;
}
regErr =
RegConnectRegistry
( hostName, hKey, &remoteKey );
if ( regErr != ERROR_SUCCESS )
{
result = NULL;
throwSpecificRegError
( env, regErr, "RegConnectRegistry()", NULL, NULL );
}
else
{
result = newRegistryKey
( env, remoteKey, jKeyName, FALSE );
}
free( hostName );
return result;
}
JNIEXPORT jobject JNICALL
Java_com_ice_jni_registry_RegistryKey_openSubKey
( JNIEnv *env, jobject rkObject,
jstring subKeyString, jint jAccess )
{
LONG regErr;
HKEY hKey;
HKEY hSubKey;
DWORD access = (DWORD)jAccess;
jstring keyName;
char *subKeyName;
jobject result = NULL;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return NULL;
subKeyName = jStringToNewAscii( env, subKeyString );
if ( subKeyName == NULL )
{
throwOutOfMemoryError( env, "jStringToNewAscii" );
return NULL;
}
access =
((jAccess == 0) ? KEY_READ :
((jAccess == 1) ? KEY_READ :
((jAccess == 2) ? KEY_WRITE :
((jAccess == 3) ? KEY_EXECUTE :
((jAccess == 4) ? KEY_ALL_ACCESS :
KEY_READ
)))));
regErr = RegOpenKeyEx( hKey, subKeyName, 0, access, &hSubKey);
if ( regErr != ERROR_SUCCESS )
{
result = NULL;
throwSpecificRegError
( env, regErr, "RegOpenKeyEx()", subKeyName, NULL );
}
else
{
keyName = buildFullKeyName( env, rkObject, subKeyName );
if ( isThrowing( env ) )
result = NULL;
else
{
result = newRegistryKey
( env, hSubKey, keyName, FALSE );
}
}
free( subKeyName );
return result;
}
JNIEXPORT jobject JNICALL
Java_com_ice_jni_registry_RegistryKey_createSubKey
( JNIEnv *env, jobject rkObject, jstring subKeyString,
jstring jClassName, jint jAccess )
{
LONG regErr;
HKEY hKey;
HKEY hSubKey;
DWORD disposition;
DWORD access = (DWORD)jAccess;
jstring keyName;
char *className;
char *subKeyName;
jobject result = NULL;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return NULL;
subKeyName = jStringToNewAscii( env, subKeyString );
if ( subKeyName == NULL )
{
throwOutOfMemoryError( env, "jStringToNewAscii(subKeyName)" );
return NULL;
}
className = NULL;
if ( jClassName != NULL )
className = jStringToNewAscii( env, jClassName );
if ( className == NULL )
{
throwRegErrorException
( env, ERROR_INVALID_PARAMETER, "null classname" );
return NULL;
}
access =
((jAccess == 0) ? KEY_READ :
((jAccess == 1) ? KEY_READ :
((jAccess == 2) ? KEY_WRITE :
((jAccess == 3) ? KEY_EXECUTE :
((jAccess == 4) ? KEY_ALL_ACCESS :
KEY_READ
)))));
regErr =
RegCreateKeyEx
( hKey, subKeyName, 0, className,
REG_OPTION_NON_VOLATILE, access,
NULL, &hSubKey, &disposition );
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegCreateKeyEx()" );
result = NULL;
}
else
{
keyName = buildFullKeyName( env, rkObject, subKeyName );
if ( isThrowing( env ) )
result = NULL;
else
{
result =
newRegistryKey
( env, hSubKey, keyName,
(disposition == REG_CREATED_NEW_KEY) );
}
}
free( subKeyName );
return result;
}
JNIEXPORT void JNICALL
Java_com_ice_jni_registry_RegistryKey_closeKey
( JNIEnv *env, jobject rkObject )
{
HKEY hKey;
LONG regErr;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return;
regErr = RegCloseKey( hKey );
}
JNIEXPORT void JNICALL
Java_com_ice_jni_registry_RegistryKey_deleteValue
( JNIEnv *env, jobject rkObject, jstring valueName )
{
HKEY hKey;
LONG regErr;
char *lpValueName;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return;
lpValueName = jStringToNewAscii( env, valueName );
if ( lpValueName == NULL )
{
throwOutOfMemoryError( env, "jStringToNewAscii" );
return;
}
regErr = RegDeleteValue( hKey, lpValueName );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegDeleteValue()", NULL, lpValueName );
}
free( lpValueName );
}
JNIEXPORT void JNICALL
Java_com_ice_jni_registry_RegistryKey_deleteSubKey
( JNIEnv *env, jobject rkObject, jstring subKey )
{
HKEY hKey;
LONG regErr;
char *lpSubKey;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return;
lpSubKey = jStringToNewAscii( env, subKey );
if ( lpSubKey == NULL )
{
throwOutOfMemoryError( env, "jStringToNewAscii" );
return;
}
regErr = RegDeleteKey( hKey, lpSubKey );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegDeleteKey()", lpSubKey, NULL );
}
free( lpSubKey );
}
JNIEXPORT void JNICALL
Java_com_ice_jni_registry_RegistryKey_flushKey
( JNIEnv *env, jobject rkObject )
{
HKEY hKey;
LONG regErr;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return;
regErr = RegFlushKey( hKey );
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegDeleteKey()" );
}
}
JNIEXPORT jstring JNICALL
Java_com_ice_jni_registry_RegistryKey_getStringValue
( JNIEnv *env, jobject rkObject, jstring valueName )
{
HKEY hKey;
LONG regErr;
LPBYTE szBuf;
LPTSTR asciiName;
jstring result = NULL;
LONG lBufSize = 0;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return NULL;
asciiName = jStringToNewAscii( env, valueName );
if ( asciiName == NULL )
{
throwOutOfMemoryError( env, "getting ascii valueName from Java string" );
return NULL;
}
regErr =
RegQueryValueEx
( hKey, asciiName, NULL, NULL, NULL, &lBufSize );
if ( regErr != ERROR_SUCCESS && regErr != ERROR_MORE_DATA )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, asciiName );
free( asciiName );
return NULL;
}
szBuf = malloc( lBufSize + 8 );
if ( szBuf == NULL )
{
throwOutOfMemoryError( env, "allocating string buffer" );
free( asciiName );
return NULL;
}
regErr =
RegQueryValueEx
( hKey, asciiName, NULL, NULL, szBuf, &lBufSize );
if ( regErr != ERROR_SUCCESS )
{
result = NULL;
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, asciiName );
}
else
{
result = asciiToJString( env, szBuf );
}
free( szBuf );
free( asciiName );
return result;
}
JNIEXPORT jstring JNICALL
Java_com_ice_jni_registry_RegistryKey_getDefaultValue
( JNIEnv *env, jobject rkObject )
{
HKEY hKey;
LONG regErr;
LONG lBufSize;
LPBYTE lpBuffer;
jstring result = NULL;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return NULL;
regErr =
RegQueryValueEx
( hKey, NULL, NULL, NULL, NULL, &lBufSize);
if ( regErr != ERROR_SUCCESS && regErr != ERROR_MORE_DATA )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, "(default)" );
return NULL;
}
lpBuffer = malloc( lBufSize + 8 );
regErr =
RegQueryValueEx
( hKey, NULL, NULL, NULL, lpBuffer, &lBufSize);
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, "(default)" );
return NULL;
}
result = asciiToJString( env, lpBuffer );
if ( result == NULL )
{
throwOutOfMemoryError( env, "allocating Java string" );
}
return result;
}
JNIEXPORT jboolean JNICALL
Java_com_ice_jni_registry_RegistryKey_hasDefaultValue
( JNIEnv *env, jobject rkObject )
{
HKEY hKey;
LONG regErr;
LONG lBufSize = 0;
jboolean result = JNI_FALSE;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return JNI_FALSE;
regErr =
RegQueryValueEx
( hKey, NULL, NULL, NULL, NULL, &lBufSize );
if ( regErr != ERROR_SUCCESS )
{
result = JNI_FALSE;
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, "(default)" );
}
else if ( lBufSize > 1 )
{
result = JNI_TRUE;
}
return result;
}
JNIEXPORT jboolean JNICALL
Java_com_ice_jni_registry_RegistryKey_hasOnlyDefaultValue
( JNIEnv *env, jobject rkObject )
{
HKEY hKey;
LONG regErr;
DWORD dwNumValues = 0 ;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return JNI_FALSE;
regErr =
RegQueryInfoKey(
hKey, NULL, NULL, NULL, NULL, NULL, NULL,
&dwNumValues, NULL, NULL, NULL, NULL );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryInfoKey()", "(default)", NULL );
return JNI_FALSE;
}
if ( dwNumValues != 1 )
return JNI_FALSE;
return
Java_com_ice_jni_registry_RegistryKey_hasDefaultValue
( env, rkObject );
}
JNIEXPORT void JNICALL
Java_com_ice_jni_registry_RegistryKey_setValue
( JNIEnv *env, jobject rkObject,
jstring valueName, jobject valueObject )
{
HKEY hKey;
DWORD dwType;
char *asciiName;
jboolean result = JNI_FALSE;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return;
dwType = getRegistryValueType( env, valueObject );
if ( isThrowing( env ) )
return;
if ( dwType < REG_NONE
|| dwType > REG_RESOURCE_REQUIREMENTS_LIST )
{
throwRegErrorException
( env, ERROR_INVALID_PARAMETER, "RegistryValue.type" );
return;
}
asciiName = jStringToNewAscii( env, valueName );
if ( asciiName != NULL )
{
setKeyValue
( env, hKey, asciiName, dwType, valueObject );
free( asciiName );
}
return;
}
JNIEXPORT jint JNICALL
Java_com_ice_jni_registry_RegistryKey_getNumberSubkeys
( JNIEnv *env, jobject rkObject )
{
HKEY hKey;
LONG regErr;
jint result = 0;
DWORD dwNumSubkeys;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return 0;
regErr =
RegQueryInfoKey(
hKey, NULL, NULL, NULL, &dwNumSubkeys,
NULL, NULL, NULL, NULL, NULL, NULL, NULL );
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegQueryInfoKey()" );
return 0;
}
return (jint) dwNumSubkeys;
}
JNIEXPORT jint JNICALL
Java_com_ice_jni_registry_RegistryKey_getMaxSubkeyLength
( JNIEnv *env, jobject rkObject )
{
HKEY hKey;
LONG regErr;
jint result = 0;
DWORD dwMaxSubkeyLength;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return 0;
regErr = maxSubKeyLength( hKey, &dwMaxSubkeyLength );
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegQueryInfoKey()" );
return 0;
}
return (jint)dwMaxSubkeyLength;
}
JNIEXPORT jstring JNICALL
Java_com_ice_jni_registry_RegistryKey_regEnumKey
( JNIEnv *env, jobject rkObject, jint index )
{
HKEY hKey;
LONG regErr;
LPTSTR keyBuf;
FILETIME lastTime;
DWORD dwIndex = (DWORD) index;
DWORD dwKeyBufSize, maxLen;
jstring result = NULL;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return NULL;
regErr = maxSubKeyLength( hKey, &maxLen );
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegQueryInfoKey()" );
return NULL;
}
dwKeyBufSize = maxLen + 2;
keyBuf = malloc( dwKeyBufSize );
if ( keyBuf == NULL )
{
throwOutOfMemoryError( env, "allocating key name buffer" );
return NULL;
}
regErr =
RegEnumKeyEx
( hKey, dwIndex, keyBuf, &dwKeyBufSize,
NULL, NULL, NULL, &lastTime );
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegEnumKeyEx()" );
return NULL;
}
result = asciiToJString( env, keyBuf );
free( keyBuf );
return result;
}
JNIEXPORT jstring JNICALL
Java_com_ice_jni_registry_RegistryKey_regEnumValue
( JNIEnv *env, jobject rkObject, jint index )
{
HKEY hKey;
jstring result = NULL;
LONG regErr;
char *nameBuf;
DWORD dwNameBufSize, maxLen;
DWORD dwIndex = (DWORD)index;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return NULL;
regErr = maxValueNameLength( hKey, &maxLen );
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegQueryInfoKey()" );
return NULL;
}
dwNameBufSize = maxLen + 2;
nameBuf = malloc( dwNameBufSize );
if ( nameBuf == NULL )
{
throwOutOfMemoryError( env, "allocating value name buffer" );
return NULL;
}
regErr =
RegEnumValue
( hKey, dwIndex, nameBuf, &dwNameBufSize,
NULL, NULL, NULL, NULL );
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegEnumValue()" );
return NULL;
}
result = asciiToJString( env, nameBuf );
free( nameBuf );
return result;
}
JNIEXPORT jint JNICALL
Java_com_ice_jni_registry_RegistryKey_getNumberValues
( JNIEnv *env, jobject rkObject )
{
HKEY hKey;
LONG regErr;
DWORD dwNumValues;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return 0;
regErr =
RegQueryInfoKey(
hKey, NULL, NULL, NULL, NULL, NULL,
NULL, &dwNumValues, NULL, NULL, NULL, NULL );
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegQueryInfoKey()" );
return 0;
}
return (jint) dwNumValues;
}
JNIEXPORT jint JNICALL
Java_com_ice_jni_registry_RegistryKey_getMaxValueDataLength
( JNIEnv *env, jobject rkObject )
{
HKEY hKey;
LONG regErr;
DWORD dwValueLen;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return 0;
regErr =
RegQueryInfoKey(
hKey, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, &dwValueLen, NULL, NULL);
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegQueryInfoKey()" );
return 0;
}
return (jint) dwValueLen;
}
JNIEXPORT jint JNICALL
Java_com_ice_jni_registry_RegistryKey_getMaxValueNameLength
( JNIEnv *env, jobject rkObject )
{
HKEY hKey;
LONG regErr;
DWORD dwNameLen;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return 0;
regErr =
RegQueryInfoKey(
hKey, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, &dwNameLen, NULL, NULL, NULL);
if ( regErr != ERROR_SUCCESS )
{
throwRegErrorException( env, regErr, "RegQueryInfoKey()" );
return 0;
}
return (jint) dwNameLen;
}
JNIEXPORT jint JNICALL
Java_com_ice_jni_registry_RegistryKey_incrDoubleWord
( JNIEnv *env, jobject rkObject, jstring valueName )
{
HKEY hKey;
LONG regErr;
jint result = 0;
char *lpValueName;
DWORD dw = 0;
DWORD size = sizeof(dw);
DWORD type = REG_DWORD;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return 0;
lpValueName = jStringToNewAscii( env, valueName );
if ( lpValueName == NULL )
{
throwOutOfMemoryError
( env, "allocating valueName ascii string" );
return 0;
}
regErr =
RegQueryValueEx
( hKey, lpValueName, 0, &type, (LPBYTE)&dw, &size );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, lpValueName );
free( lpValueName );
return 0;
}
// reinitialize dw if is not REG_DWORD or buffer_overflow
if ( type != REG_DWORD )
dw = 0;
dw++;
regErr =
RegSetValueEx
( hKey, lpValueName, 0,
REG_DWORD, (LPBYTE)&dw, size );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegSetValueEx()", NULL, lpValueName );
dw = 0;
}
free( lpValueName );
return (jint) dw;
}
JNIEXPORT jint JNICALL
Java_com_ice_jni_registry_RegistryKey_decrDoubleWord
( JNIEnv *env, jobject rkObject, jstring valueName )
{
HKEY hKey;
LONG regErr;
jint result = 0;
char *lpValueName;
DWORD dw = 0;
DWORD size = sizeof(dw);
DWORD type = REG_DWORD;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return 0;
lpValueName = jStringToNewAscii( env, valueName );
if ( lpValueName == NULL )
{
throwOutOfMemoryError( env, "allocating valueName ascii string" );
return 0;
}
regErr =
RegQueryValueEx
( hKey, lpValueName, 0,
&type, (LPBYTE)&dw, &size );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, lpValueName );
free( lpValueName );
return 0;
}
if ( type != REG_DWORD )
dw = 0;
dw--;
regErr =
RegSetValueEx
( hKey, lpValueName, 0,
REG_DWORD, (LPBYTE)&dw, size );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegSetValueEx()", NULL, lpValueName );
dw = 0;
}
free( lpValueName );
return (jint) dw;
}
JNIEXPORT jobject JNICALL
Java_com_ice_jni_registry_RegistryKey_getValue
( JNIEnv *env, jobject rkObject, jstring valueName )
{
HKEY hKey;
LONG regErr;
jclass valClass;
jarray binData;
jarray stringArray;
jstring dataString;
jmethodID methodID;
jobject newValue;
jobject result = NULL;
char *lpValueName;
char *className;
char *methodSignature;
DWORD type, dwDataSize;
DWORD dwValue;
hKey = getRegistryKey( env, rkObject );
if ( isThrowing( env ) )
return NULL;
lpValueName = jStringToNewAscii( env, valueName );
if ( lpValueName == NULL )
{
throwOutOfMemoryError( env, "allocating valueName ascii string" );
return NULL;
}
regErr =
RegQueryValueEx
( hKey, lpValueName, 0, &type, NULL, &dwDataSize );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, lpValueName );
free( lpValueName );
return NULL;
}
className = "CLASS_WAS_NEVER_SET";
methodSignature = "METHOD_SIGNATURE_WAS_NOT_SET";
switch ( type )
{
case REG_SZ:
case REG_EXPAND_SZ:
className = "com/ice/jni/registry/RegStringValue";
methodSignature = "(Ljava/lang/String;)V";
break;
case REG_MULTI_SZ:
className = "com/ice/jni/registry/RegMultiStringValue";
methodSignature = "([Ljava/lang/String;)V";
break;
case REG_DWORD:
case REG_DWORD_BIG_ENDIAN:
className = "com/ice/jni/registry/RegDWordValue";
methodSignature = "(I)V";
break;
case REG_BINARY:
className = "com/ice/jni/registry/RegBinaryValue";
methodSignature = "([B)V";
break;
}
valClass = (*env)->FindClass( env, className );
if ( valClass == NULL )
{
throwNoClassDefError( env, className );
return NULL;
}
methodID =
(*env)->GetMethodID
( env, valClass, "setData", methodSignature );
if ( methodID == NULL )
{
throwNoSuchMethodError
( env, className, "setData", methodSignature );
return NULL;
}
newValue =
newRegistryValue
( env, rkObject, valueName, className, (jint)type );
if ( isThrowing( env ) )
return NULL;
switch ( type )
{
case REG_MULTI_SZ:
stringArray =
getMultiStringValueData( env, hKey, lpValueName );
if ( isThrowing( env ) )
return NULL;
(*env)->CallVoidMethod
( env, newValue, methodID, stringArray );
break;
case REG_SZ:
case REG_EXPAND_SZ:
dataString =
getStringValueData( env, hKey, lpValueName );
if ( isThrowing( env ) )
return NULL;
(*env)->CallVoidMethod
( env, newValue, methodID, dataString );
break;
case REG_DWORD:
// UNDONE - Do we need to deal with BIG_ENDIAN?
dwValue = getDWordValueData( env, hKey, lpValueName );
if ( isThrowing( env ) )
return NULL;
(*env)->CallVoidMethod
( env, newValue, methodID, (jint)dwValue );
break;
case REG_BINARY:
binData = getBinaryValueData( env, hKey, lpValueName );
if ( isThrowing( env ) )
return NULL;
(*env)->CallVoidMethod
( env, newValue, methodID, binData );
break;
}
return newValue;
}
JNIEXPORT jstring JNICALL
Java_com_ice_jni_registry_RegistryKey_expandEnvStrings
( JNIEnv *env, jclass rkClass, jstring jExpandStr )
{
DWORD expLen;
LPTSTR lpExpandStr;
LPTSTR lpExpandResult;
jstring result = NULL;
char countBuf[8];
lpExpandStr = jStringToNewAscii( env, jExpandStr );
if ( lpExpandStr == NULL )
{
throwOutOfMemoryError( env, "ascii-ifying expand string" );
return NULL;
}
expLen = ExpandEnvironmentStrings
( lpExpandStr, countBuf, 1 );
lpExpandResult = malloc( expLen + 8 );
if ( lpExpandResult == NULL )
{
throwOutOfMemoryError( env, "allocating expand result" );
return NULL;
}
expLen = ExpandEnvironmentStrings
( lpExpandStr, lpExpandResult, expLen );
result = strbufToJString( env, lpExpandResult, (int)expLen );
free( lpExpandResult );
if ( result == NULL )
{
throwOutOfMemoryError( env, "allocating jstring result" );
return NULL;
}
return result;
}
HKEY
getRegistryKey( JNIEnv *env, jobject rkObject )
{
jclass rkClass;
jfieldID jfid;
jint jHKey;
rkClass = (*env)->GetObjectClass( env, rkObject );
if ( rkClass == NULL )
{
throwNoClassDefError( env, "RegistryKey" );
return 0;
}
jfid = (*env)->GetFieldID( env, rkClass, "hKey", "I" );
if ( jfid == 0 )
{
throwNoSuchFieldError( env, "hKey" );
return 0;
}
jHKey = (*env)->GetIntField( env, rkObject, jfid );
return (HKEY) jHKey;
}
jstring
getRegistryKeyName( JNIEnv *env, jobject rkObject )
{
jfieldID jfid;
jstring jName;
jclass rkClass;
rkClass = (*env)->GetObjectClass( env, rkObject );
if ( rkClass == NULL )
{
throwNoClassDefError( env, "RegistryKey" );
return NULL;
}
jfid =
(*env)->GetFieldID
( env, rkClass, "name", "Ljava/lang/String;" );
if ( jfid == 0 )
{
throwNoSuchFieldError( env, "name" );
return NULL;
}
jName = (*env)->GetObjectField( env, rkObject, jfid );
if ( jName == NULL )
{
throwOutOfMemoryError( env, "GetObjectField(name)" );
return NULL;
}
return jName;
}
jstring
buildFullKeyName( JNIEnv *env, jobject rkObject, char *subKeyName )
{
jstring jName;
int dataLen;
jstring result = NULL;
char *namePtr = NULL;
char *newNamePtr = NULL;
jName = getRegistryKeyName( env, rkObject );
if ( isThrowing( env ) )
return NULL;
namePtr = jStringToNewAscii( env, jName );
if ( namePtr == NULL )
{
throwOutOfMemoryError( env, "jStringToNewAscii(name)" );
return NULL;
}
dataLen = strlen( namePtr ) + strlen( subKeyName ) + 2;
newNamePtr = malloc( dataLen );
if ( newNamePtr == NULL )
{
throwOutOfMemoryError( env, "malloc(newNamePtr)" );
}
else
{
sprintf( newNamePtr, "%s\\%s", namePtr, subKeyName );
result = asciiToJString( env, newNamePtr );
}
free( namePtr );
free( newNamePtr );
return result;
}
DWORD
getRegistryValueType( JNIEnv *env, jobject valueObject )
{
jfieldID jfid;
jint jType;
jclass valClass;
valClass = (*env)->GetObjectClass( env, valueObject );
if ( valClass == NULL )
{
throwNoClassDefError( env, "RegistryValue" );
return JNI_FALSE;
}
jfid = (*env)->GetFieldID( env, valClass, "type", "I" );
if ( jfid == 0 )
{
throwNoSuchFieldError( env, "type" );
return JNI_FALSE;
}
jType = (*env)->GetIntField( env, valueObject, jfid );
return (int) jType;
}
void
setKeyValue(
JNIEnv *env, HKEY hKey, char *valueName,
DWORD dwType, jobject valObject )
{
int i;
LONG regErr;
DWORD dataLen;
DWORD dwValue;
LPBYTE ptr;
LPBYTE dataPtr;
jint jIntVal, numStr, sLen;
jboolean isCopied;
jclass valClass;
jstring jStr;
jfieldID jfid;
jarray jBinArray, jStrArray;
jarray freeArray = NULL;
LPBYTE freePtr = NULL;
char emptyBuf[4];
valClass = (*env)->GetObjectClass( env, valObject );
if ( valClass == NULL )
{
throwNoClassDefError
( env, "setKeyValue: getting RegistryValue class" );
return;
}
switch ( dwType )
{
case REG_SZ:
case REG_EXPAND_SZ:
jfid = (*env)->GetFieldID
( env, valClass, "data", "Ljava/lang/String;" );
if ( jfid == 0 )
{
throwNoSuchFieldError( env, "setKeyValue: String data" );
return;
}
jStr = (*env)->GetObjectField( env, valObject, jfid );
if ( jStr == NULL )
{
throwOutOfMemoryError( env, "GetObjectField(data)" );
return;
}
dataPtr = freePtr = jStringToNewAscii( env, jStr );
if ( dataPtr == NULL )
{
throwOutOfMemoryError
( env, "setKeyValue: jStringToNewAscii" );
return;
}
dataLen = strlen( dataPtr ) + 1;
break;
case REG_MULTI_SZ:
jfid = (*env)->GetFieldID
( env, valClass, "data", "[Ljava/lang/String;" );
if ( jfid == 0 )
{
throwNoSuchFieldError( env, "setKeyValue: String[] data" );
return;
}
jStrArray = (jarray)
(*env)->GetObjectField( env, valObject, jfid );
if ( jStrArray == NULL )
{
throwOutOfMemoryError( env, "GetObjectField(data)" );
return;
}
numStr = (*env)->GetArrayLength( env, jStrArray );
for ( dataLen = 0, i = 0 ; i < numStr ; ++i )
{
jStr = (jstring)
(*env)->GetObjectArrayElement
( env, jStrArray, i );
sLen = (*env)->GetStringLength( env, jStr );
dataLen += sLen + 1;
}
dataLen++; // remember double null to terminate array...
dataPtr = freePtr = malloc( dataLen + 32 );
if ( dataPtr == NULL )
{
throwOutOfMemoryError( env, "setKeyValue: dataPtr" );
return;
}
for ( ptr = dataPtr, i = 0 ; i < numStr ; ++i )
{
jStr = (jstring)
(*env)->GetObjectArrayElement
( env, jStrArray, i );
if ( jStr == NULL )
{
sLen = 0;
}
else
{
sLen = (*env)->GetStringLength( env, jStr );
jStringToAscii( env, jStr, ptr, (sLen + 1) );
}
ptr += sLen;
*ptr++ = '\0';
}
*ptr++ = '\0'; // remember double null to terminate...
break;
case REG_DWORD:
case REG_DWORD_BIG_ENDIAN:
jfid = (*env)->GetFieldID( env, valClass, "data", "I" );
if ( jfid == 0 )
{
throwNoSuchFieldError( env, "setKeyValue: int data" );
return;
}
jIntVal = (*env)->GetIntField( env, valObject, jfid );
dwValue = (DWORD)jIntVal;
dataPtr = (LPBYTE) &dwValue;
dataLen = sizeof( dwValue );
break;
case REG_BINARY:
jfid = (*env)->GetFieldID( env, valClass, "data", "[B" );
if ( jfid == 0 )
{
throwNoSuchFieldError( env, "setKeyValue: byte[] data" );
return;
}
jBinArray = (jarray)
(*env)->GetObjectField( env, valObject, jfid );
if ( jBinArray == NULL )
{
dataLen = 0;
dataPtr = emptyBuf;
}
else
{
freeArray = jBinArray;
dataLen = (*env)->GetArrayLength( env, jBinArray );
dataPtr = (LPBYTE)
(*env)->GetByteArrayElements
( env, jBinArray, &isCopied );
if ( dataPtr == NULL )
{
throwOutOfMemoryError
( env, "setKeyValue: GetByteArrayElements" );
return;
}
}
break;
}
regErr =
RegSetValueEx
( hKey, valueName, 0, dwType, dataPtr, dataLen );
if ( freePtr != NULL )
free( freePtr );
if ( freeArray != NULL )
(*env)->ReleaseByteArrayElements
( env, freeArray, dataPtr, JNI_ABORT );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegSetValueEx()", NULL, NULL );
}
}
BOOL
RegIsHKeyRemote( HKEY hKey )
{
DWORD dw = (DWORD)hKey;
if ( (hKey >= HKEY_CLASSES_ROOT)
&& (hKey <= HKEY_DYN_DATA) )
{
return FALSE; // local
}
return ( ( (~dw) & 1 ) == 0 );
}
LONG
maxSubKeyLength( HKEY hKey, DWORD *pdwSubkeyLen )
{
LONG regErr;
regErr =
RegQueryInfoKey(
hKey, NULL, NULL, NULL, NULL,
pdwSubkeyLen, NULL, NULL, NULL,
NULL, NULL, NULL );
// NOTE
// This algorithm is due to a bug related to remote
// registries in Win95. This fix comes from pp 129-130
// in the "Inside The Windows 95 Registry" book from
// O'Reilly & Assocvates, First Edition.
//
if ( regErr == ERROR_SUCCESS && RegIsHKeyRemote( hKey ) )
{
*pdwSubkeyLen = (*pdwSubkeyLen * 2) + 2;
}
return regErr;
}
LONG
maxValueNameLength( HKEY hKey, DWORD *pdwNameLen )
{
LONG regErr;
regErr =
RegQueryInfoKey(
hKey, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, pdwNameLen, NULL, NULL, NULL );
// REVIEW Where does this algorithm come from?
if ( regErr == ERROR_SUCCESS && RegIsHKeyRemote( hKey ) )
{
*pdwNameLen = (*pdwNameLen * 2) + 2;
}
return regErr;
}
DWORD
getDWordValueData( JNIEnv *env, HKEY hKey, char *valueName )
{
LONG regErr;
DWORD dwType;
DWORD dwValue = 0;
DWORD dwBufSize = sizeof(dwValue);
regErr =
RegQueryValueEx
( hKey, valueName, NULL, &dwType, (LPBYTE)&dwValue, &dwBufSize );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, valueName );
return 0;
}
if ( dwType != REG_DWORD || dwType == REG_DWORD_BIG_ENDIAN )
{
throwRegErrorException
( env, ERROR_INVALID_PARAMETER, "type is not REG_DWORD" );
return 0;
}
return dwValue;
}
jarray
getMultiStringValueData( JNIEnv *env, HKEY hKey, char *valueName )
{
jarray result;
int i, start, sLen, count, cnt;
LONG regErr;
char *strData;
char *className;
jstring jStr;
jclass strClass;
DWORD dwType;
DWORD dwBufSize = 0;
regErr =
RegQueryValueEx
( hKey, valueName, NULL, &dwType, NULL, &dwBufSize );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, valueName );
return NULL;
}
if ( dwType != REG_MULTI_SZ )
{
throwRegErrorException
( env, ERROR_INVALID_PARAMETER, "type is not REG_MULTI_SZ" );
return NULL;
}
strData = malloc( dwBufSize + 8 );
if ( strData == NULL )
{
throwOutOfMemoryError
( env, "setKeyValue: getMultiStringValueData: strData" );
return NULL;
}
regErr =
RegQueryValueEx
( hKey, valueName, NULL, &dwType, strData, &dwBufSize );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, valueName );
free( strData );
return NULL;
}
for ( count = 0, i = 0 ; i < (int)dwBufSize ; ++i )
{
if ( strData[i] == '\0' )
{
++count;
if ( strData[ i + 1 ] == '\0' )
break;
}
}
className = "java/lang/String";
strClass = (*env)->FindClass( env, className );
if ( strClass == NULL )
{
throwNoClassDefError( env, className );
return NULL;
}
result =
(*env)->NewObjectArray
( env, (jsize)count, strClass, NULL );
if ( result == NULL )
{
throwOutOfMemoryError
( env, "getMultiStringValueData: NewObjectArray" );
return NULL;
}
for ( cnt = 0, start = 0, i = 0
; i < (int)dwBufSize && cnt < count ; ++i )
{
if ( strData[i] == '\0' )
{
sLen = (i - start);
jStr = strbufToJString( env, &strData[start], sLen );
if ( jStr == NULL )
{
throwOutOfMemoryError
( env, "getMultiStringValueData: strbufToJString" );
return NULL;
}
(*env)->SetObjectArrayElement
( env, result, (jsize)cnt++, jStr );
start = i + 1;
if ( strData[ start ] == '\0' )
break;
}
}
return result;
}
jstring
getStringValueData( JNIEnv *env, HKEY hKey, char *valueName )
{
DWORD i;
LONG regErr;
char *strData;
jchar *uniBuf;
jstring result = NULL;
DWORD dwType;
DWORD dwBufSize = 0;
regErr =
RegQueryValueEx
( hKey, valueName, NULL, &dwType, NULL, &dwBufSize );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, valueName );
return NULL;
}
if ( dwType != REG_SZ || dwType == REG_EXPAND_SZ )
{
throwRegErrorException
( env, ERROR_INVALID_PARAMETER, "type is not REG_SZ" );
return NULL;
}
strData = malloc( dwBufSize + 8 );
if ( strData == NULL )
{
throwOutOfMemoryError
( env, "getStringValueData: strData" );
return NULL;
}
regErr =
RegQueryValueEx
( hKey, valueName, NULL, &dwType, strData, &dwBufSize );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, valueName );
free( strData );
return NULL;
}
uniBuf = (jchar *)
malloc( sizeof(jchar) * (dwBufSize + 2) );
if ( uniBuf == NULL )
{
throwOutOfMemoryError
( env, "getStringValueData: uniBuf" );
return NULL;
}
--dwBufSize;
for ( i = 0 ; i < dwBufSize ; ++i )
uniBuf[i] = (jchar) strData[i];
result =
(*env)->NewString
( env, uniBuf, (jsize)dwBufSize );
free( uniBuf );
return result;
}
jarray
getBinaryValueData( JNIEnv *env, HKEY hKey, char *valueName )
{
LONG regErr;
char *regData;
jstring result = NULL;
DWORD dwType;
DWORD dwBufSize = 0;
jarray binBytes = NULL;
regErr =
RegQueryValueEx
( hKey, valueName, NULL, &dwType, NULL, &dwBufSize );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, valueName );
return NULL;
}
if ( dwType != REG_BINARY )
{
throwRegErrorException
( env, ERROR_INVALID_PARAMETER, "type is not REG_BINARY" );
return NULL;
}
regData = malloc( dwBufSize + 8 );
if ( regData == NULL )
{
throwOutOfMemoryError
( env, "getBinaryValueData: regData" );
return NULL;
}
regErr =
RegQueryValueEx
( hKey, valueName, NULL, &dwType, regData, &dwBufSize );
if ( regErr != ERROR_SUCCESS )
{
throwSpecificRegError
( env, regErr, "RegQueryValueEx()", NULL, valueName );
free( regData );
return NULL;
}
binBytes = (*env)->NewByteArray( env, (jsize)dwBufSize );
if ( regData == NULL )
{
throwOutOfMemoryError
( env, "getBinaryValueData: binBytes" );
return NULL;
}
(*env)->SetByteArrayRegion
( env, binBytes, 0, (jsize)dwBufSize, regData );
return binBytes;
}
jstring
asciiToJString( JNIEnv *env, char *asciiStr )
{
return strbufToJString( env, asciiStr, strlen(asciiStr) );
}
jstring
strbufToJString( JNIEnv *env, char *buf, int len )
{
int i;
jchar *uniBuf;
jstring result = NULL;
uniBuf = (jchar *)
malloc( sizeof(jchar) * (len + 1) );
if ( uniBuf != NULL )
{
for ( i = 0 ; i < len ; ++i )
uniBuf[i] = (jchar) buf[i];
result = (*env)->NewString( env, uniBuf, (jsize)len );
free( uniBuf );
}
return result;
}
char *
jStringToNewAscii( JNIEnv *env, jstring jStr )
{
int i;
int utfLen;
jboolean isCopy;
char *asciiBuf;
const char *utfBuf;
utfLen = (*env)->GetStringUTFLength( env, jStr );
utfBuf = (*env)->GetStringUTFChars( env, jStr, &isCopy );
asciiBuf = malloc( utfLen + 2 );
if ( asciiBuf != NULL )
{
for ( i = 0 ; i < utfLen ; ++i )
asciiBuf[i] = utfBuf[i];
asciiBuf[i] = '\0';
(*env)->ReleaseStringUTFChars( env, jStr, utfBuf );
}
return asciiBuf;
}
void
jStringToAscii
( JNIEnv *env, jstring jStr, char *asciiBuf, int asciiLen )
{
int i;
int utfLen;
jboolean isCopy;
const char *utfBuf;
utfLen = (*env)->GetStringUTFLength( env, jStr );
utfBuf = (*env)->GetStringUTFChars( env, jStr, &isCopy );
if ( utfBuf != NULL )
{
for ( i = 0 ; i < utfLen && i < (asciiLen - 1) ; ++i )
asciiBuf[i] = utfBuf[i];
asciiBuf[i] = '\0';
(*env)->ReleaseStringUTFChars( env, jStr, utfBuf );
}
}
jobject
newRegistryKey( JNIEnv *env, HKEY hKey, jstring keyName, BOOL created )
{
jclass rkClass;
jobject newKey;
jmethodID methodID;
jboolean cFlag = (jboolean) created;
char *methodName = "<init>";
char *methodSignature = "(ILjava/lang/String;Z)V";
char *className = "com/ice/jni/registry/RegistryKey";
rkClass = (*env)->FindClass( env, className );
if ( rkClass == NULL )
{
throwNoClassDefError( env, (char *)className );
return NULL;
}
methodID =
(*env)->GetMethodID
( env, rkClass, methodName, methodSignature );
if ( methodID == NULL )
{
throwNoSuchMethodError
( env, className, methodName, methodSignature );
return NULL;
}
newKey =
(*env)->NewObject
( env, rkClass, methodID,
(jint)hKey, keyName, (jboolean)cFlag );
return newKey;
}
jobject
newRegistryValue(
JNIEnv *env, jobject rkObject,
jstring valueName, char *className, int type )
{
jclass rkClass;
jobject newValue;
jmethodID methodID;
char *methodName = "<init>";
char *methodSignature =
"(Lcom/ice/jni/registry/RegistryKey;Ljava/lang/String;I)V";
rkClass = (*env)->FindClass( env, className );
if ( rkClass == NULL )
{
throwNoClassDefError( env, className );
return NULL;
}
methodID =
(*env)->GetMethodID
( env, rkClass, methodName, methodSignature );
if ( methodID == NULL )
{
throwNoSuchMethodError
( env, className, methodName, methodSignature );
return NULL;
}
newValue =
(*env)->NewObject
( env, rkClass, methodID, rkObject, valueName, (jint)type );
return newValue;
}
BOOL
isThrowing( JNIEnv *env )
{
return ( (*env)->ExceptionOccurred(env) != NULL );
}
jint
throwNoSuchKeyException( JNIEnv *env, char *message )
{
jclass exClass;
char *className =
"com/ice/jni/registry/NoSuchKeyException";
exClass = (*env)->FindClass( env, className );
if ( exClass == NULL )
{
return throwNoClassDefError( env, className );
}
return (*env)->ThrowNew( env, exClass, message );
}
jint
throwNoSuchValueException( JNIEnv *env, char *message )
{
jclass exClass;
char *className =
"com/ice/jni/registry/NoSuchValueException";
exClass = (*env)->FindClass( env, className );
if ( exClass == NULL )
{
return throwNoClassDefError( env, className );
}
return (*env)->ThrowNew( env, exClass, message );
}
void
throwSpecificRegError
( JNIEnv *env, LONG regErr, char *message,
char *keyName, char *valueName )
{
char msgBuf[512];
if ( regErr != ERROR_FILE_NOT_FOUND
|| ( keyName == NULL && valueName == NULL ) )
{
throwRegErrorException( env, regErr, message );
}
else if ( keyName != NULL )
{
sprintf( msgBuf, "%.200s, key='%.200s'", message, keyName );
throwNoSuchKeyException( env, msgBuf );
}
else
{
sprintf( msgBuf, "%.200s, value='%.200s'", message, valueName );
throwNoSuchValueException( env, msgBuf );
}
}
jint
throwRegErrorException( JNIEnv *env, LONG regErr, char *message )
{
jclass exClass;
jmethodID methodID;
jobject exObject;
jstring jMsgString;
char strBuf[512];
char *regDescription = "";
char *className = "com/ice/jni/registry/RegistryException";
char *methodSignature = "(Ljava/lang/String;I)V";
exClass = (*env)->FindClass( env, className );
if ( exClass == NULL )
{
return throwNoClassDefError( env, className );
}
methodID =
(*env)->GetMethodID
( env, exClass, "<init>", methodSignature );
if ( methodID == NULL )
{
return throwNoSuchMethodError
( env, className, "<init>", methodSignature );
}
jMsgString = strbufToJString( env, message, strlen(message) );
if ( jMsgString == NULL )
{
return throwOutOfMemoryError
( env, "throwRegErrorException: creating message string" );
}
exObject =
(*env)->NewObject
( env, exClass, methodID, jMsgString, (jint)regErr );
switch ( regErr )
{
case ERROR_FILE_NOT_FOUND:
regDescription = "not found";
break;
case ERROR_ACCESS_DENIED:
regDescription = "access denied";
break;
case ERROR_INVALID_HANDLE:
regDescription = "invalid handle";
break;
case ERROR_INVALID_PARAMETER:
regDescription = "invalid parameter";
break;
case ERROR_CALL_NOT_IMPLEMENTED:
regDescription = "call not implemented";
break;
case ERROR_INSUFFICIENT_BUFFER:
regDescription = "insufficient buffer";
break;
case ERROR_LOCK_FAILED:
regDescription = "lock failed";
break;
case ERROR_MORE_DATA:
regDescription = "more data";
break;
case ERROR_NO_MORE_ITEMS:
regDescription = "no more items";
break;
case ERROR_BADDB:
regDescription = "bad DB";
break;
case ERROR_BADKEY:
regDescription = "bad key";
break;
case ERROR_CANTOPEN:
regDescription = "can not open";
break;
case ERROR_CANTREAD:
regDescription = "can not read";
break;
case ERROR_CANTWRITE:
regDescription = "can not write";
break;
case ERROR_REGISTRY_RECOVERED:
regDescription = "registry recovered";
break;
case ERROR_REGISTRY_CORRUPT:
regDescription = "registry corrupt";
break;
case ERROR_REGISTRY_IO_FAILED:
regDescription = "registry IO failed";
break;
case ERROR_NOT_REGISTRY_FILE:
regDescription = "not a registry file";
break;
case ERROR_KEY_DELETED:
regDescription = "key has been deleted";
break;
}
sprintf( strBuf,
"Registry API Error %d, '%.128s' - '%.256s'",
regErr, regDescription, message );
return (*env)->ThrowNew( env, exClass, strBuf );
}
jint
throwNoClassDefError( JNIEnv *env, char *message )
{
jclass exClass;
char *className = "java/lang/NoClassDefFoundError";
exClass = (*env)->FindClass( env, className );
if ( exClass == NULL )
{
return throwNoClassDefError( env, className );
}
return (*env)->ThrowNew( env, exClass, message );
}
jint
throwNoSuchMethodError(
JNIEnv *env, char *className, char *methodName, char *signature )
{
jclass exClass;
char *exClassName = "java/lang/NoSuchMethodError";
LPTSTR msgBuf;
exClass = (*env)->FindClass( env, exClassName );
if ( exClass == NULL )
{
return throwNoClassDefError( env, exClassName );
}
msgBuf = malloc( strlen(className) + strlen(methodName)
+ strlen(signature) + 8 );
if ( msgBuf == NULL )
{
return throwOutOfMemoryError
( env, "throwNoSuchMethodError: allocatinf msgBuf" );
}
strcpy( msgBuf, className );
strcat( msgBuf, "." );
strcat( msgBuf, methodName );
strcat( msgBuf, "." );
strcat( msgBuf, signature );
return (*env)->ThrowNew( env, exClass, msgBuf );
}
jint
throwNoSuchFieldError( JNIEnv *env, char *message )
{
jclass exClass;
char *className = "java/lang/NoSuchFieldError";
exClass = (*env)->FindClass( env, className );
if ( exClass == NULL )
{
return throwNoClassDefError( env, className );
}
return (*env)->ThrowNew( env, exClass, message );
}
jint
throwOutOfMemoryError( JNIEnv *env, char *message )
{
jclass exClass;
char *className = "java/lang/OutOfMemoryError";
exClass = (*env)->FindClass( env, className );
if ( exClass == NULL )
{
return throwNoClassDefError( env, className );
}
return (*env)->ThrowNew( env, exClass, message );
}