Back to index

lightning-sunbird  0.9+nobinonly
CSecureEnv.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the MRJ Carbon OJI Plugin.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corp.
00018  * Portions created by the Initial Developer are Copyright (C) 2001
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Patrick C. Beard <beard@netscape.com>
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "CSecureEnv.h"
00039 #include "nsISecurityContext.h"
00040 
00041 #include "MRJPlugin.h"
00042 #include "MRJSession.h"
00043 #include "nsIThreadManager.h"
00044 #include "nsIJVMManager.h"
00045 #include "nsIScriptSecurityManager.h"
00046 #include "nsIPrincipal.h"
00047 
00048 #include "MRJMonitor.h"
00049 #include "NativeMonitor.h"
00050 #include "JavaMessageQueue.h"
00051 
00052 #define PROXY_JNI_CALLS 1
00053 #define USE_LIVECONNECT_PROXY 1
00054 #define LOCAL_REFS_ARE_GLOBAL USE_LIVECONNECT_PROXY
00055 
00056 inline jobject ToGlobalRef(JNIEnv* env, jobject localRef)
00057 {
00058     jobject globalRef = env->NewGlobalRef(localRef);
00059     // env->DeleteLocalRef(localRef);   // not necessary from native methods. done en-masse.
00060     return globalRef;
00061 }
00062 
00063 JavaMessageQueue::JavaMessageQueue(Monitor* monitor)
00064        :      mFirst(NULL), mLast(NULL), mMonitor(monitor)
00065 {
00066 }
00067 
00068 void JavaMessageQueue::putMessage(JavaMessage* msg)
00069 {
00070        if (mFirst == NULL) {
00071               mFirst = mLast = msg;
00072        } else {
00073               mLast->setNext(msg);
00074               mLast = msg;
00075        }
00076        msg->setNext(NULL);
00077 }
00078 
00079 JavaMessage* JavaMessageQueue::getMessage()
00080 {
00081        JavaMessage* msg = mFirst;
00082        if (msg != NULL) {
00083               mFirst = mFirst->getNext();
00084               if (mFirst == NULL) mLast = NULL;
00085        }
00086        return msg;
00087 }
00088 
00089 void JavaMessageQueue::enter()
00090 {
00091        mMonitor->enter();
00092 }
00093 
00094 void JavaMessageQueue::exit()
00095 {
00096        mMonitor->exit();
00097 }
00098 
00099 void JavaMessageQueue::wait()
00100 {
00101        mMonitor->wait();
00102 }
00103 
00104 void JavaMessageQueue::wait(long long millis)
00105 {
00106        mMonitor->wait(millis);
00107 }
00108 
00109 void JavaMessageQueue::notify()
00110 {
00111        mMonitor->notify();
00112 }
00113 
00117 static void netscape_oji_JNIThread_run(JNIEnv* env, jobject self)
00118 {
00119        CSecureEnv* secureEnv = NULL;
00120        jmethodID yieldMethod = NULL;
00121        jmethodID sleepMethod = NULL;
00122        
00123        jclass clazz = env->GetObjectClass(self);
00124        if (clazz != NULL) {
00125               // the field fSecureEnv contains a pointer to a CSecureEnv.
00126               jfieldID fSecureEnvField = env->GetFieldID(clazz, "fSecureEnv", "I");
00127               if (fSecureEnvField != NULL) {
00128                      secureEnv = (CSecureEnv*) env->GetIntField(self, fSecureEnvField);
00129               }
00130               yieldMethod = env->GetStaticMethodID(clazz, "yield", "()V");
00131               sleepMethod = env->GetStaticMethodID(clazz, "sleep", "(J)V");
00132        }
00133        
00134        // notify the secure JNI that we are here, and wait for messages to arrive.
00135        if (secureEnv != NULL) {
00136               jboolean isRunning = true;
00137               MRJSession* session = secureEnv->getSession();
00138               MRJMonitor requestMonitor(session, self);
00139               MRJMonitor replyMonitor(session);
00140               // NativeMonitor replyMonitor(secureEnv->getThreadManager());
00141               JavaMessageQueue requests(&requestMonitor), replies(&replyMonitor);
00142               secureEnv->initialize(env, &isRunning, &requests, &replies);
00143               
00144               // when this thread is running, no other thread can enter the request queue monitor.
00145               requests.enter();
00146               
00147               while (isRunning) {
00148                      // the protocol for now is dead simple:  get a message from the
00149                      // requests message queue, process it, and then put it back in
00150                      // the replies queue. This will get more elaborate to handle
00151                      // upcall requests. 
00152                      JavaMessage* msg = requests.getMessage();
00153                      if (msg != NULL) {
00154                             msg->execute(env);
00155                             secureEnv->savePendingException(env);
00156                             replies.putMessage(msg);
00157                             replies.notify();
00158                      } else {
00159                             // should we do sleep, timed wait, or what?
00160                             // env->CallStaticVoidMethod(clazz, yieldMethod);
00161                             // env->CallStaticVoidMethod(clazz, sleepMethod, jlong(kDefaultJMTime));
00162                             requests.wait();
00163                      }
00164               }
00165               
00166               requests.exit();
00167        }
00168 }
00169 
00170 static jclass netscape_oji_JNIRunnable;
00171 static jmethodID netscape_oji_JNIRunnable_constructorID;
00172 static jfieldID netscape_oji_JNIRunnable_mJavaMessageID;
00173 
00174 static void netscape_oji_JNIRunnable_run(JNIEnv* env, jobject self)
00175 {
00176     JavaMessage* msg = (JavaMessage*) env->GetIntField(self, netscape_oji_JNIRunnable_mJavaMessageID);
00177     if (msg) {
00178         msg->execute(env);
00179         // what about upcalls?
00180     }
00181 }
00182 
00183 static bool check_exceptions(JNIEnv* env)
00184 {
00185     jthrowable exc = env->ExceptionOccurred();
00186        if (exc) {
00187            env->ExceptionDescribe();
00188            env->ExceptionClear();
00189            env->DeleteLocalRef(exc);
00190            return true;
00191        }
00192        return false;
00193 }
00194 
00199 static void CreateJNIThread(CSecureEnv* secureEnv)
00200 {
00201        nsIThreadManager* manager = secureEnv->getThreadManager();
00202        MRJSession* session = secureEnv->getSession();
00203        JNIEnv* env = session->getCurrentEnv();
00204        
00205     check_exceptions(env);
00206 
00207        jclass JNIThreadClass = env->FindClass("netscape.oji.JNIThread");
00208        if (JNIThreadClass != NULL) {
00209               JNINativeMethod method = { "run", "()V", &netscape_oji_JNIThread_run };
00210               env->RegisterNatives(JNIThreadClass, &method, 1);
00211               jmethodID constructorID = env->GetMethodID(JNIThreadClass, "<init>", "(I)V");
00212               if (constructorID != NULL) {
00213                      jobject javaThread = env->NewObject(JNIThreadClass, constructorID, secureEnv);
00214                      for (;;) {
00215                             // was there some kind of exception? bail if so.
00216                             if (check_exceptions(env))
00217                                 break;
00218                             // give time to Java, to allow the thread to come up.
00219                             session->idle();
00220                             // has the thread made contact?
00221                             if (secureEnv->isInitialized())
00222                                    break;
00223                             // give time to NSPR, to avoid hanging too long.
00224                             manager->Sleep();
00225                      }
00226               }
00227               env->DeleteLocalRef(JNIThreadClass);
00228        }
00229 }
00230 
00231 static jobject CreateJNIRunnable(JNIEnv* env, JavaMessage* msg)
00232 {
00233     // XXX:  does this have to be thread safe?
00234     if (!netscape_oji_JNIRunnable) {
00235        jclass clazz = env->FindClass("netscape.oji.JNIRunnable");
00236        if (!clazz) return NULL;
00237               JNINativeMethod method = { "run", "()V", &netscape_oji_JNIRunnable_run };
00238               env->RegisterNatives(clazz, &method, 1);
00239               netscape_oji_JNIRunnable_constructorID = env->GetMethodID(clazz, "<init>", "(I)V");
00240         netscape_oji_JNIRunnable_mJavaMessageID = env->GetFieldID(clazz, "mJavaMessage", "I");
00241               netscape_oji_JNIRunnable = (jclass) env->NewGlobalRef(clazz);
00242               env->DeleteLocalRef(clazz);
00243     }
00244     check_exceptions(env);
00245     return env->NewObject(netscape_oji_JNIRunnable, netscape_oji_JNIRunnable_constructorID, msg);
00246 }
00247 
00248 static jclass GetLiveConnectProxy(JNIEnv* env, nsIPrincipal* codebasePrincipal)
00249 {
00250     jclass liveConnectProxy = NULL;
00251     jclass netscape_oji_ProxyClassLoaderFactory = env->FindClass("netscape/oji/ProxyClassLoaderFactory");
00252     if (netscape_oji_ProxyClassLoaderFactory) {
00253         jmethodID createClassLoaderID = env->GetStaticMethodID(netscape_oji_ProxyClassLoaderFactory,
00254                                                                "createClassLoader", 
00255                                                                "(Ljava/lang/String;)Ljava/lang/ClassLoader;");
00256         if (createClassLoaderID) {
00257             jstring codebaseUTF = NULL;
00258             char* codebase;
00259             nsresult rv = codebasePrincipal->GetOrigin(&codebase);
00260             if (NS_SUCCEEDED(rv)) {
00261                 codebaseUTF = env->NewStringUTF(codebase);
00262                 delete[] codebase;
00263             }
00264             if (codebaseUTF) {
00265                 jobject classLoader = env->CallStaticObjectMethod(netscape_oji_ProxyClassLoaderFactory,
00266                                                                   createClassLoaderID, codebaseUTF);
00267                 if (classLoader) {
00268                     jclass clazz = env->GetObjectClass(classLoader);
00269                     jmethodID loadClassID = env->GetMethodID(clazz, "loadClass",
00270                                                              "(Ljava/lang/String;)Ljava/lang/Class;");
00271                     if (loadClassID) {
00272                         jstring className = env->NewStringUTF("netscape.oji.LiveConnectProxy");
00273                         if (className) {
00274                             liveConnectProxy = (jclass) env->CallObjectMethod(classLoader, loadClassID, className);
00275                             env->DeleteLocalRef(className);
00276                         }
00277                     }
00278                     env->DeleteLocalRef(clazz);
00279                 }
00280                 env->DeleteLocalRef(codebaseUTF);
00281             }
00282         }
00283         env->DeleteLocalRef(netscape_oji_ProxyClassLoaderFactory);
00284     }
00285     check_exceptions(env);
00286     return liveConnectProxy;
00287 }
00288 
00292 class CreateNativeThreadMessage : public NativeMessage {
00293        nsresult* mResult;
00294        PRUint32* mThreadID;
00295        CSecureEnv* mSecureEnv;
00296 public:
00297        CreateNativeThreadMessage(nsresult* outResult, PRUint32* outThreadID, CSecureEnv* secureEnv)
00298               :      mResult(outResult), mThreadID(outThreadID), mSecureEnv(secureEnv)
00299        {
00300        }
00301 
00302        virtual void execute()
00303        {
00304               nsIThreadManager* manager = mSecureEnv->getThreadManager();
00305               *mResult = manager->CreateThread(mThreadID, mSecureEnv);
00306        }
00307 };
00308 
00312 static void CreateNativeThread(CSecureEnv* secureEnv)
00313 {
00314        nsresult result;
00315        PRUint32 threadID;
00316        MRJSession* session = secureEnv->getSession();
00317        
00318        // cause a native thread to be created on our behalf. Perhaps this should be a message we send to the
00319        // session itself. otherwise we could have reentrancy problems.
00320        CreateNativeThreadMessage message(&result, &threadID, secureEnv);
00321        session->sendMessage(&message);
00322 
00323        if (session->onMainThread()) {
00324               // give time to other native threads, so the new thread can come up.
00325               nsIThreadManager* manager = secureEnv->getThreadManager();
00326               while (!secureEnv->isInitialized()) {
00327                      manager->Sleep();
00328               }
00329        } else {
00330               // sleep the current Java thread until we rendezvous with the Native thread.
00331               JNIEnv* env = session->getCurrentEnv();
00332               jclass threadClass = env->FindClass("java/lang/Thread");
00333               if (threadClass != NULL) {
00334                      jmethodID sleepMethod = env->GetStaticMethodID(threadClass, "sleep", "(J)V");
00335                      if (sleepMethod != NULL) {
00336                             while (!secureEnv->isInitialized())
00337                                    env->CallStaticVoidMethod(threadClass, sleepMethod, jlong(1024));
00338                      }
00339                      env->DeleteLocalRef(threadClass);
00340               }
00341        }
00342 }
00343 
00347 NS_IMETHODIMP CSecureEnv::Run()
00348 {
00349        jboolean isRunning = true;
00350        NativeMonitor requestMonitor(mSession, mThreadManager);
00351        MRJMonitor replyMonitor(mSession);
00352        JavaMessageQueue requests(&requestMonitor), replies(&replyMonitor);
00353        // initialize(env, self, &isRunning, &requests, &replies);
00354        
00355        // we have to create the Proxy JNI here, so it associated with this thread.
00356        nsIJVMManager* manager = mPlugin->getManager();
00357        manager->CreateProxyJNI(this, &mProxyEnv);
00358        
00359        mIsRunning = &isRunning;
00360        mNativeQueue = &requests;
00361        mJavaQueue = &replies;
00362        
00363        // when this thread is running, no other thread can enter the request queue monitor.
00364        requests.enter();
00365        
00366        while (isRunning) {
00367               // the protocol for now is dead simple:  get a message from the
00368               // requests message queue, process it, and then put it back in
00369               // the replies queue. This will get more elaborate to handle
00370               // upcall requests. 
00371               JavaMessage* msg = requests.getMessage();
00372               if (msg != NULL) {
00373                      msg->execute(mProxyEnv);
00374                      replies.putMessage(msg);
00375                      replies.notify();
00376               } else {
00377                      // should we do sleep, timed wait, or what?
00378                      // env->CallStaticVoidMethod(clazz, yieldMethod);
00379                      // env->CallStaticVoidMethod(clazz, sleepMethod, jlong(kDefaultJMTime));
00380                      requests.wait();
00381               }
00382        }
00383        
00384        requests.exit();
00385 
00386        return NS_OK;
00387 }
00388 
00392 void CSecureEnv::sendMessageToJava(JavaMessage* msg)
00393 {
00394 #if USE_LIVECONNECT_PROXY
00395     JNIEnv* env = mSession->getCurrentEnv();
00396     // XXX this needs to be optimized up the wazoo.
00397     // somehow, get the associated class loader for the codebase of the currently running
00398     // script. doing this here would require us to use lots of unfrozen interfaces.
00399     nsresult rv = NS_OK;
00400     if (!mScriptSecurityManager) {
00401         rv = MRJPlugin::GetService("@mozilla.org/scriptsecuritymanager;1",
00402                                    NS_GET_IID(nsIScriptSecurityManager),
00403                                    (void**)&mScriptSecurityManager);
00404     }
00405     // XXX Simple principal caching mechanism. If the principal is the same as
00406     // last time, then keep using the same LiveConnect proxy class. This should
00407     // be adequate for the simple cases of a single document using LiveConnect.
00408     // There should also be some caching going on inside ProxyClassLoaderFactory,
00409     // which should return the same class loader for the same URL, until this
00410     // prinicipal changes. Idea:  could use a weak reference dictionary that
00411     // only holds the class loader while there are other strong references to it.
00412     if (NS_SUCCEEDED(rv)) {
00413         nsIPrincipal* scriptPrincipal;
00414         rv = mScriptSecurityManager->GetSubjectPrincipal(&scriptPrincipal);
00415         if (NS_SUCCEEDED(rv)) {
00416             if (scriptPrincipal != mScriptPrincipal) {
00417                 // invalidate our cached LiveConnectProxy class.
00418                 NS_IF_RELEASE(mScriptPrincipal);
00419                 mScriptPrincipal = scriptPrincipal;
00420                 if (mLiveConnectProxy) {
00421                     env->DeleteGlobalRef(mLiveConnectProxy);
00422                     mLiveConnectProxy = NULL;
00423                 }
00424             }
00425             if (!mLiveConnectProxy && scriptPrincipal) {
00426                 jclass liveConnectProxy = GetLiveConnectProxy(env, scriptPrincipal);
00427                 if (liveConnectProxy) {
00428                     mLiveConnectProxy = (jclass) env->NewGlobalRef(liveConnectProxy);
00429                     env->DeleteLocalRef(liveConnectProxy);
00430                 }
00431             }
00432         }
00433     }
00434     if (mLiveConnectProxy) {
00435         jobject runnable = CreateJNIRunnable(env, msg);
00436         if (runnable) {
00437             jmethodID runID = env->GetStaticMethodID(mLiveConnectProxy, "run", "(Ljava/lang/Runnable;)V");
00438             if (runID) {
00439                 env->CallStaticVoidMethod(mLiveConnectProxy, runID, runnable);
00440                 savePendingException(env);
00441             }
00442             env->DeleteLocalRef(runnable);
00443         }
00444     } else {
00445         msg->execute(env);
00446         savePendingException(env);
00447     }
00448 #else
00449        messageLoop(mProxyEnv, msg, mJavaQueue, mNativeQueue, true);
00450 #endif
00451 }
00452 
00456 void CSecureEnv::sendMessageFromJava(JNIEnv* javaEnv, JavaMessage* msg, Boolean busyWaiting)
00457 {
00458        messageLoop(javaEnv, msg, mNativeQueue, mJavaQueue, busyWaiting);
00459 }
00460 
00462 // Table-driven nsISupports data.
00463 
00464 const InterfaceInfo CSecureEnv::sInterfaces[] = {
00465        { NS_ISECUREENV_IID, INTERFACE_OFFSET(CSecureEnv, nsISecureEnv) },
00466        { NS_IRUNNABLE_IID, INTERFACE_OFFSET(CSecureEnv, nsIRunnable) },
00467 };
00468 const UInt32 CSecureEnv::kInterfaceCount = sizeof(sInterfaces) / sizeof(InterfaceInfo);
00469 
00470 CSecureEnv::CSecureEnv(MRJPlugin* plugin, JNIEnv* proxyEnv, JNIEnv* javaEnv)
00471        :      SupportsMixin(this, sInterfaces, kInterfaceCount),
00472               mPlugin(plugin), mProxyEnv(proxyEnv), mJavaEnv(javaEnv),
00473               mSession(plugin->getSession()), mThreadManager(plugin->getThreadManager()),
00474               mIsRunning(NULL), mJavaQueue(NULL), mNativeQueue(NULL),
00475               mPendingException(NULL),
00476               mScriptSecurityManager(NULL), mScriptPrincipal(NULL), mLiveConnectProxy(NULL)
00477 {
00478        // need to create the JNIThread for communicating with Java.
00479        if (mJavaEnv != NULL)
00480         CreateNativeThread(this);
00481        else
00482            CreateJNIThread(this);
00483 }
00484 
00485 
00486 CSecureEnv::~CSecureEnv()  
00487 {
00488        // Tell the Java thread to die.
00489        if (mIsRunning != NULL) {
00490               *mIsRunning = false;
00491               mJavaQueue->notify();
00492        }
00493 
00494     JNIEnv* env = mSession->getCurrentEnv();
00495     if (mPendingException) {
00496         env->DeleteGlobalRef(mPendingException);
00497         mPendingException = NULL;
00498     }
00499     
00500     if (mLiveConnectProxy) {
00501         env->DeleteGlobalRef(mLiveConnectProxy);
00502         mLiveConnectProxy = NULL;
00503     }
00504     
00505     NS_IF_RELEASE(mScriptPrincipal);
00506     NS_IF_RELEASE(mScriptSecurityManager);
00507 }
00508 
00509 void CSecureEnv::initialize(JNIEnv* javaEnv, jboolean* isRunning, JavaMessageQueue* javaQueue, JavaMessageQueue* nativeQueue)
00510 {
00511        mJavaEnv = javaEnv;
00512        mIsRunning = isRunning;
00513        mJavaQueue = javaQueue;
00514        mNativeQueue = nativeQueue;
00515 }
00516 
00518 // CSecureEnv::Create
00520 // Create the CSecureEnv object for creating object, invoking method, 
00521 // getting/setting field in JNI with security context.
00522 //
00523 // parameters :
00524 //
00525 // return :
00526 // 
00527 // notes :
00528 //
00529 NS_METHOD
00530 CSecureEnv::Create(MRJPlugin* plugin, JNIEnv* proxyEnv, const nsIID& aIID, void* *aInstancePtr)
00531 {
00532        CSecureEnv* secureEnv = new CSecureEnv(plugin, proxyEnv);
00533        if (secureEnv == NULL)
00534            return NS_ERROR_OUT_OF_MEMORY;
00535        NS_ADDREF(secureEnv);
00536        nsresult rv = secureEnv->QueryInterface(aIID, aInstancePtr);
00537        NS_RELEASE(secureEnv);
00538        return rv;
00539 }
00540 
00542 // CSecureEnv::NewObject
00544 // Create new Java object in LiveConnect.
00545 //
00546 // @param env        -- JNIEnv pointer.
00547 // @param clazz      -- Java Class object.
00548 // @param methodID   -- Method id
00549 // @param args       -- arguments for invoking the constructor.
00550 // @param result     -- return new Java object.
00551 // @param ctx        -- security context 
00552 //
00553 
00554 class NewObjectMessage : public JavaMessage {
00555        jclass clazz;
00556        jmethodID methodID;
00557        jvalue* args;
00558        jobject* result;
00559 
00560 public:
00561        NewObjectMessage(jclass clazz,  jmethodID methodID, jvalue *args, jobject* result)
00562        {
00563               this->clazz = clazz;
00564               this->methodID = methodID;
00565               this->args = args;
00566               this->result = result;
00567        }
00568        
00569        virtual void execute(JNIEnv* env)
00570        {
00571               *result = env->NewObjectA(clazz, methodID, args);
00572 #if LOCAL_REFS_ARE_GLOBAL
00573         *result = ToGlobalRef(env, *result);
00574 #endif
00575        }
00576 };
00577 
00578 NS_IMETHODIMP CSecureEnv::NewObject(/*[in]*/  jclass clazz, 
00579                                     /*[in]*/  jmethodID methodID, 
00580                                     /*[in]*/  jvalue *args, 
00581                                     /*[out]*/ jobject* result,
00582                                     /*[in]*/  nsISecurityContext* ctx)
00583 {
00584     if (clazz == NULL || methodID == NULL)
00585         return NS_ERROR_NULL_POINTER;
00586 
00587 #if PROXY_JNI_CALLS
00588     // Call method on Java side
00589     NewObjectMessage msg(clazz, methodID, args, result);
00590     sendMessageToJava(&msg);
00591 #else
00592        *result = mJavaEnv->NewObjectA(clazz, methodID, args);
00593 #endif
00594        
00595        return NS_OK;
00596 }
00597 
00598 
00600 // CSecureEnv::CallMethod
00602 // Invoke method on Java object in LiveConnect.
00603 //
00604 // @param type       -- Return type
00605 // @param obj        -- Java object.
00606 // @param methodID   -- Method id
00607 // @param result     -- return result of invocation.
00608 // @param ctx        -- security context 
00609 //
00610 
00611 class CallMethodMessage : public JavaMessage {
00612        jni_type return_type;
00613        jobject obj;
00614        jmethodID methodID;
00615        jvalue* args;
00616        jvalue* result;
00617 
00618 public:
00619        CallMethodMessage(jni_type return_type, jobject obj, jmethodID methodID, jvalue *args, jvalue* result)
00620        {
00621               this->return_type = return_type;
00622               this->obj = obj;
00623               this->methodID = methodID;
00624               this->args = args;
00625               this->result = result;
00626        }
00627        
00628        virtual void execute(JNIEnv* env)
00629        {
00630               switch (return_type) {
00631               case jobject_type:
00632                      result->l = env->CallObjectMethodA(obj, methodID, args);
00633 #if LOCAL_REFS_ARE_GLOBAL
00634             result->l = ToGlobalRef(env, result->l);
00635 #endif
00636                      break;
00637               case jboolean_type:
00638                      result->z = env->CallBooleanMethodA(obj, methodID, args);
00639                      break;
00640               case jbyte_type:
00641                      result->b = env->CallByteMethodA(obj, methodID, args);
00642                      break;
00643               case jchar_type:
00644                      result->c = env->CallCharMethodA(obj, methodID, args);
00645                      break;
00646               case jshort_type:
00647                      result->s = env->CallShortMethodA(obj, methodID, args);
00648                      break;
00649               case jint_type:
00650                      result->i = env->CallIntMethodA(obj, methodID, args);
00651                      break;
00652               case jlong_type:
00653                      result->j = env->CallLongMethodA(obj, methodID, args);
00654                      break;
00655               case jfloat_type:
00656                      result->f = env->CallFloatMethodA(obj, methodID, args);
00657                      break;
00658               case jdouble_type:
00659                      result->d = env->CallDoubleMethodA(obj, methodID, args);
00660                      break;
00661               case jvoid_type:
00662                      env->CallVoidMethodA(obj, methodID, args);
00663                      break;
00664               }
00665        }
00666 };
00667 
00668 NS_IMETHODIMP CSecureEnv::CallMethod(/*[in]*/  jni_type return_type,
00669                                       /*[in]*/  jobject obj, 
00670                                       /*[in]*/  jmethodID methodID, 
00671                                       /*[in]*/  jvalue *args, 
00672                                       /*[out]*/ jvalue* result,
00673                                       /*[in]*/  nsISecurityContext* ctx)
00674 {
00675     if (obj == NULL || methodID == NULL)
00676         return NS_ERROR_NULL_POINTER;
00677 
00678 #if PROXY_JNI_CALLS
00679        // Call method on Java side
00680        // return CallJavaMethod(obj, method, args, ctx, result);
00681        CallMethodMessage msg(return_type, obj, methodID, args, result);
00682        sendMessageToJava(&msg);
00683 #else
00684     JNIEnv* env = mJavaEnv;
00685        switch (return_type) {
00686        case jobject_type:
00687               result->l = env->CallObjectMethodA(obj, methodID, args);
00688               break;
00689        case jboolean_type:
00690               result->z = env->CallBooleanMethodA(obj, methodID, args);
00691               break;
00692        case jbyte_type:
00693               result->b = env->CallByteMethodA(obj, methodID, args);
00694               break;
00695        case jchar_type:
00696               result->c = env->CallCharMethodA(obj, methodID, args);
00697               break;
00698        case jshort_type:
00699               result->s = env->CallShortMethodA(obj, methodID, args);
00700               break;
00701        case jint_type:
00702               result->i = env->CallIntMethodA(obj, methodID, args);
00703               break;
00704        case jlong_type:
00705               result->j = env->CallLongMethodA(obj, methodID, args);
00706               break;
00707        case jfloat_type:
00708               result->f = env->CallFloatMethodA(obj, methodID, args);
00709               break;
00710        case jdouble_type:
00711               result->d = env->CallDoubleMethodA(obj, methodID, args);
00712               break;
00713        case jvoid_type:
00714               env->CallVoidMethodA(obj, methodID, args);
00715               break;
00716        }
00717 #endif
00718        
00719        return NS_OK;
00720 }
00721 
00722 
00724 // CSecureEnv::CallNonvirtualMethod
00726 // Invoke non-virtual method on Java object in LiveConnect.
00727 //
00728 // @param obj        -- Java object.
00729 // @param methodID   -- Method id
00730 // @param args       -- arguments for invoking the constructor.
00731 // @param result     -- return result of invocation.
00732 // @param ctx        -- security context 
00733 //
00734 
00735 class CallNonvirtualMethodMessage : public JavaMessage {
00736        jni_type type;
00737        jobject obj;
00738        jclass clazz;
00739        jmethodID methodID;
00740        jvalue* args;
00741        jvalue* result;
00742 
00743 public:
00744        CallNonvirtualMethodMessage(jni_type type, jobject obj, jclass clazz, jmethodID methodID, jvalue *args, jvalue* result)
00745        {
00746               this->type = type;
00747               this->obj = obj;
00748               this->clazz = clazz;
00749               this->methodID = methodID;
00750               this->args = args;
00751               this->result = result;
00752        }
00753        
00754        virtual void execute(JNIEnv* env)
00755        {
00756               switch (type) {
00757               case jobject_type:
00758                      result->l = env->CallNonvirtualObjectMethodA(obj, clazz, methodID, args);
00759 #if LOCAL_REFS_ARE_GLOBAL
00760             result->l = ToGlobalRef(env, result->l);
00761 #endif
00762                      break;
00763               case jboolean_type:
00764                      result->z = env->CallNonvirtualBooleanMethodA(obj, clazz, methodID, args);
00765                      break;
00766               case jbyte_type:
00767                      result->b = env->CallNonvirtualByteMethodA(obj, clazz, methodID, args);
00768                      break;
00769               case jchar_type:
00770                      result->c = env->CallNonvirtualCharMethodA(obj, clazz, methodID, args);
00771                      break;
00772               case jshort_type:
00773                      result->s = env->CallNonvirtualShortMethodA(obj, clazz, methodID, args);
00774                      break;
00775               case jint_type:
00776                      result->i = env->CallNonvirtualIntMethodA(obj, clazz, methodID, args);
00777                      break;
00778               case jlong_type:
00779                      result->j = env->CallNonvirtualLongMethodA(obj, clazz, methodID, args);
00780                      break;
00781               case jfloat_type:
00782                      result->f = env->CallNonvirtualFloatMethodA(obj, clazz, methodID, args);
00783                      break;
00784               case jdouble_type:
00785                      result->d = env->CallNonvirtualDoubleMethodA(obj, clazz, methodID, args);
00786                      break;
00787               case jvoid_type:
00788                      env->CallNonvirtualVoidMethodA(obj, clazz, methodID, args);
00789                      break;
00790               }
00791        }
00792 };
00793 
00794 NS_IMETHODIMP CSecureEnv::CallNonvirtualMethod(/*[in]*/  jni_type type,
00795                                                 /*[in]*/  jobject obj, 
00796                                                 /*[in]*/  jclass clazz,
00797                                                 /*[in]*/  jmethodID methodID,
00798                                                 /*[in]*/  jvalue *args, 
00799                                                 /*[out]*/ jvalue* result,
00800                                                 /*[in]*/  nsISecurityContext* ctx)
00801 {
00802     if (obj == NULL || clazz == NULL || methodID == NULL)
00803         return NS_ERROR_NULL_POINTER;
00804 
00805 #if PROXY_JNI_CALLS
00806        // Call non-virtual method on Java side
00807        // return CallJavaMethod(obj, method, args, ctx, result);
00808        CallNonvirtualMethodMessage msg(type, obj, clazz, methodID, args, result);
00809        sendMessageToJava(&msg);
00810 #else
00811     #error "Implement me!"
00812 #endif
00813 
00814        return NS_OK;
00815 }
00816 
00817 
00819 // CSecureEnv::GetField
00821 // Get a field on Java object in LiveConnect.
00822 //
00823 // @param obj        -- Java object.
00824 // @param fieldID    -- field id
00825 // @param result     -- return field value
00826 // @param ctx        -- security context 
00827 //
00828 
00829 class GetFieldMessage : public JavaMessage {
00830        jni_type type;
00831        jobject obj;
00832        jfieldID fieldID;
00833        jvalue* result;
00834 public:
00835        GetFieldMessage(jni_type type, jobject obj, jfieldID fieldID, jvalue* result)
00836        {
00837               this->type = type;
00838               this->obj = obj;
00839               this->fieldID = fieldID;
00840               this->result = result;
00841        }
00842        
00843        virtual void execute(JNIEnv* env)
00844        {
00845               switch (type) {
00846               case jobject_type:
00847                      result->l = env->GetObjectField(obj, fieldID);
00848 #if LOCAL_REFS_ARE_GLOBAL
00849             result->l = ToGlobalRef(env, result->l);
00850 #endif
00851                      break;
00852               case jboolean_type:
00853                      result->z = env->GetBooleanField(obj, fieldID);
00854                      break;
00855               case jbyte_type:
00856                      result->b = env->GetByteField(obj, fieldID);
00857                      break;
00858               case jchar_type:
00859                      result->c = env->GetCharField(obj, fieldID);
00860                      break;
00861               case jshort_type:
00862                      result->s = env->GetShortField(obj, fieldID);
00863                      break;
00864               case jint_type:
00865                      result->i = env->GetIntField(obj, fieldID);
00866                      break;
00867               case jlong_type:
00868                      result->j = env->GetLongField(obj, fieldID);
00869                      break;
00870               case jfloat_type:
00871                      result->f = env->GetFloatField(obj, fieldID);
00872                      break;
00873               case jdouble_type:
00874                      result->d = env->GetDoubleField(obj, fieldID);
00875                      break;
00876               }
00877        }
00878 };
00879 
00880 NS_IMETHODIMP CSecureEnv::GetField(/*[in]*/  jni_type type,
00881                                    /*[in]*/  jobject obj, 
00882                                    /*[in]*/  jfieldID fieldID,
00883                                    /*[out]*/ jvalue* result,
00884                                    /*[in]*/  nsISecurityContext* ctx)
00885 {
00886     if (mJavaEnv == NULL || obj == NULL || fieldID == NULL)
00887         return NS_ERROR_NULL_POINTER;
00888 
00889 #if PROXY_JNI_CALLS
00890     // Get field on Java side
00891     GetFieldMessage msg(type, obj, fieldID, result);
00892     sendMessageToJava(&msg);
00893 #else    
00894        JNIEnv* env = mJavaEnv;
00895        switch (type) {
00896        case jobject_type:
00897               result->l = env->GetObjectField(obj, fieldID);
00898               break;
00899        case jboolean_type:
00900               result->z = env->GetBooleanField(obj, fieldID);
00901               break;
00902        case jbyte_type:
00903               result->b = env->GetByteField(obj, fieldID);
00904               break;
00905        case jchar_type:
00906               result->c = env->GetCharField(obj, fieldID);
00907               break;
00908        case jshort_type:
00909               result->s = env->GetShortField(obj, fieldID);
00910               break;
00911        case jint_type:
00912               result->i = env->GetIntField(obj, fieldID);
00913               break;
00914        case jlong_type:
00915               result->j = env->GetLongField(obj, fieldID);
00916               break;
00917        case jfloat_type:
00918               result->f = env->GetFloatField(obj, fieldID);
00919               break;
00920        case jdouble_type:
00921               result->d = env->GetDoubleField(obj, fieldID);
00922               break;
00923        }
00924 #endif
00925 
00926        return NS_OK;
00927 }
00928 
00929 
00931 // CSecureEnv::SetField
00933 //
00934 // Set a field on Java object in LiveConnect.
00935 //
00936 // @param obj        -- Java object.
00937 // @param fieldID    -- field id
00938 // @param result     -- field value to set
00939 // @param ctx        -- security context 
00940 //
00941 
00942 class SetFieldMessage : public JavaMessage {
00943        jni_type type;
00944        jobject obj;
00945        jfieldID fieldID;
00946        jvalue val;
00947 public:
00948        SetFieldMessage(jni_type type, jobject obj, jfieldID fieldID, jvalue val)
00949        {
00950               this->type = type;
00951               this->obj = obj;
00952               this->fieldID = fieldID;
00953               this->val = val;
00954        }
00955        
00956        virtual void execute(JNIEnv* env)
00957        {
00958        switch (type) {
00959        case jobject_type:
00960               env->SetObjectField(obj, fieldID, val.l);
00961               break;
00962        case jboolean_type:
00963               env->SetBooleanField(obj, fieldID, val.z);
00964               break;
00965        case jbyte_type:
00966               env->SetByteField(obj, fieldID, val.b);
00967               break;
00968        case jchar_type:
00969               env->SetCharField(obj, fieldID, val.c);
00970               break;
00971        case jshort_type:
00972               env->SetShortField(obj, fieldID, val.s);
00973               break;
00974        case jint_type:
00975               env->SetIntField(obj, fieldID, val.i);
00976               break;
00977        case jlong_type:
00978               env->SetLongField(obj, fieldID, val.j);
00979               break;
00980        case jfloat_type:
00981               env->SetFloatField(obj, fieldID, val.f);
00982               break;
00983        case jdouble_type:
00984               env->SetDoubleField(obj, fieldID, val.d);
00985               break;
00986        }
00987        }
00988 };
00989 
00990 NS_IMETHODIMP CSecureEnv::SetField(/*[in]*/ jni_type type,
00991                                     /*[in]*/ jobject obj, 
00992                                     /*[in]*/ jfieldID fieldID,
00993                                     /*[in]*/ jvalue val,
00994                                     /*[in]*/ nsISecurityContext* ctx)
00995 {
00996     if (mJavaEnv == NULL || obj == NULL || fieldID == NULL)
00997         return NS_ERROR_NULL_POINTER;
00998 
00999 #if PROXY_JNI_CALLS
01000     // Set field on Java side
01001     SetFieldMessage msg(type, obj, fieldID, val);
01002     sendMessageToJava(&msg);
01003 #else
01004        JNIEnv* env = mJavaEnv;
01005        switch (type) {
01006        case jobject_type:
01007               env->SetObjectField(obj, fieldID, val.l);
01008               break;
01009        case jboolean_type:
01010               env->SetBooleanField(obj, fieldID, val.z);
01011               break;
01012        case jbyte_type:
01013               env->SetByteField(obj, fieldID, val.b);
01014               break;
01015        case jchar_type:
01016               env->SetCharField(obj, fieldID, val.c);
01017               break;
01018        case jshort_type:
01019               env->SetShortField(obj, fieldID, val.s);
01020               break;
01021        case jint_type:
01022               env->SetIntField(obj, fieldID, val.i);
01023               break;
01024        case jlong_type:
01025               env->SetLongField(obj, fieldID, val.j);
01026               break;
01027        case jfloat_type:
01028               env->SetFloatField(obj, fieldID, val.f);
01029               break;
01030        case jdouble_type:
01031               env->SetDoubleField(obj, fieldID, val.d);
01032               break;
01033        }
01034 #endif
01035 
01036        return NS_OK;
01037 }
01038 
01039 
01041 // CSecureEnv::CallStaticMethod
01043 //
01044 // Invoke static method on Java object in LiveConnect.
01045 //
01046 // @param obj        -- Java object.
01047 // @param methodID   -- method id
01048 // @param args       -- arguments for invoking the constructor.
01049 // @param result     -- return result of invocation.
01050 // @param ctx        -- security context 
01051 //
01052 
01053 class CallStaticMethodMessage : public JavaMessage {
01054        jni_type type;
01055        jclass clazz;
01056        jmethodID methodID;
01057        jvalue* args;
01058        jvalue* result;
01059 public:
01060        CallStaticMethodMessage(jni_type type, jclass clazz, jmethodID methodID, jvalue *args, jvalue* result)
01061        {
01062               this->type = type;
01063               this->clazz = clazz;
01064               this->methodID = methodID;
01065               this->args = args;
01066               this->result = result;
01067        }
01068        
01069        virtual void execute(JNIEnv* env)
01070        {
01071               switch (type) {
01072               case jobject_type:
01073                      result->l = env->CallStaticObjectMethodA(clazz, methodID, args);
01074 #if LOCAL_REFS_ARE_GLOBAL
01075             result->l = ToGlobalRef(env, result->l);
01076 #endif
01077                      break;
01078               case jboolean_type:
01079                      result->z = env->CallStaticBooleanMethodA(clazz, methodID, args);
01080                      break;
01081               case jbyte_type:
01082                      result->b = env->CallStaticByteMethodA(clazz, methodID, args);
01083                      break;
01084               case jchar_type:
01085                      result->c = env->CallStaticCharMethodA(clazz, methodID, args);
01086                      break;
01087               case jshort_type:
01088                      result->s = env->CallStaticShortMethodA(clazz, methodID, args);
01089                      break;
01090               case jint_type:
01091                      result->i = env->CallStaticIntMethodA(clazz, methodID, args);
01092                      break;
01093               case jlong_type:
01094                      result->j = env->CallStaticLongMethodA(clazz, methodID, args);
01095                      break;
01096               case jfloat_type:
01097                      result->f = env->CallStaticFloatMethodA(clazz, methodID, args);
01098                      break;
01099               case jdouble_type:
01100                      result->d = env->CallStaticDoubleMethodA(clazz, methodID, args);
01101                      break;
01102               case jvoid_type:
01103                      env->CallStaticVoidMethodA(clazz, methodID, args);
01104                      break;
01105               }
01106        }
01107 };
01108 
01109 NS_IMETHODIMP CSecureEnv::CallStaticMethod(/*[in]*/  jni_type type,
01110                                             /*[in]*/  jclass clazz,
01111                                             /*[in]*/  jmethodID methodID,
01112                                             /*[in]*/  jvalue *args, 
01113                                             /*[out]*/ jvalue* result,
01114                                             /*[in]*/  nsISecurityContext* ctx)
01115 {
01116     if (clazz == NULL || methodID == NULL)
01117         return NS_ERROR_NULL_POINTER;
01118 
01119 #if PROXY_JNI_CALLS
01120        // Call method on Java side
01121        // return CallJavaMethod(NULL, method, args, ctx, result);
01122        CallStaticMethodMessage msg(type, clazz, methodID, args, result);
01123        sendMessageToJava(&msg);
01124 #else
01125     #error "Implement me!"
01126 #endif
01127 
01128        return NS_OK;
01129 }
01130 
01131 
01133 // CSecureEnv::GetStaticField
01135 // Get a static field on Java object in LiveConnect.
01136 //
01137 // @param obj        -- Java object.
01138 // @param fieldID    -- field id
01139 // @param result     -- return field value
01140 // @param ctx        -- security context 
01141 //
01142 
01143 class GetStaticFieldMessage : public JavaMessage {
01144        jni_type type;
01145        jclass clazz;
01146        jfieldID fieldID;
01147        jvalue* result;
01148 public:
01149        GetStaticFieldMessage(jni_type type, jclass clazz, jfieldID fieldID, jvalue* result)
01150        {
01151               this->type = type;
01152               this->clazz = clazz;
01153               this->fieldID = fieldID;
01154               this->result = result;
01155        }
01156        
01157        virtual void execute(JNIEnv* env)
01158        {
01159               switch (type) {
01160               case jobject_type:
01161                      result->l = env->GetStaticObjectField(clazz, fieldID);
01162 #if LOCAL_REFS_ARE_GLOBAL
01163             result->l = ToGlobalRef(env, result->l);
01164 #endif
01165                      break;
01166               case jboolean_type:
01167                      result->z = env->GetStaticBooleanField(clazz, fieldID);
01168                      break;
01169               case jbyte_type:
01170                      result->b = env->GetStaticByteField(clazz, fieldID);
01171                      break;
01172               case jchar_type:
01173                      result->c = env->GetStaticCharField(clazz, fieldID);
01174                      break;
01175               case jshort_type:
01176                      result->s = env->GetStaticShortField(clazz, fieldID);
01177                      break;
01178               case jint_type:
01179                      result->i = env->GetStaticIntField(clazz, fieldID);
01180                      break;
01181               case jlong_type:
01182                      result->j = env->GetStaticLongField(clazz, fieldID);
01183                      break;
01184               case jfloat_type:
01185                      result->f = env->GetStaticFloatField(clazz, fieldID);
01186                      break;
01187               case jdouble_type:
01188                      result->d = env->GetStaticDoubleField(clazz, fieldID);
01189                      break;
01190               }
01191        }
01192 };
01193 
01194 NS_IMETHODIMP CSecureEnv::GetStaticField(/*[in]*/  jni_type type,
01195                                           /*[in]*/  jclass clazz, 
01196                                           /*[in]*/  jfieldID fieldID,
01197                                           /*[out]*/ jvalue* result,
01198                                           /*[in]*/  nsISecurityContext* ctx)
01199 {
01200     if (mJavaEnv == NULL || clazz == NULL || fieldID == NULL)
01201         return NS_ERROR_NULL_POINTER;
01202 
01203 #if PROXY_JNI_CALLS
01204     // Get static field on Java side
01205        GetStaticFieldMessage msg(type, clazz, fieldID, result);
01206        sendMessageToJava(&msg);
01207 #else
01208     // This doesn't work in Mac OS X.
01209        // should be able to perform in Java env.
01210        JNIEnv* env = mJavaEnv;
01211        switch (type) {
01212        case jobject_type:
01213               result->l = env->GetStaticObjectField(clazz, fieldID);
01214               break;
01215        case jboolean_type:
01216               result->z = env->GetStaticBooleanField(clazz, fieldID);
01217               break;
01218        case jbyte_type:
01219               result->b = env->GetStaticByteField(clazz, fieldID);
01220               break;
01221        case jchar_type:
01222               result->c = env->GetStaticCharField(clazz, fieldID);
01223               break;
01224        case jshort_type:
01225               result->s = env->GetStaticShortField(clazz, fieldID);
01226               break;
01227        case jint_type:
01228               result->i = env->GetStaticIntField(clazz, fieldID);
01229               break;
01230        case jlong_type:
01231               result->j = env->GetStaticLongField(clazz, fieldID);
01232               break;
01233        case jfloat_type:
01234               result->f = env->GetStaticFloatField(clazz, fieldID);
01235               break;
01236        case jdouble_type:
01237               result->d = env->GetStaticDoubleField(clazz, fieldID);
01238               break;
01239        }
01240 #endif
01241 
01242        return NS_OK;
01243 }
01244 
01245 
01247 // CSecureEnv::SetStaticField
01249 // Set a static field on Java object in LiveConnect.
01250 //
01251 // @param obj        -- Java object.
01252 // @param fieldID    -- field id
01253 // @param result     -- field value to set
01254 // @param ctx        -- security context 
01255 //
01256 
01257 class SetStaticFieldMessage : public JavaMessage {
01258        jni_type type;
01259        jclass clazz;
01260        jfieldID fieldID;
01261        jvalue val;
01262 public:
01263        SetStaticFieldMessage(jni_type type, jclass clazz, jfieldID fieldID, jvalue val)
01264        {
01265               this->type = type;
01266               this->clazz = clazz;
01267               this->fieldID = fieldID;
01268               this->val = val;
01269        }
01270        
01271        virtual void execute(JNIEnv* env)
01272        {
01273        switch (type) {
01274        case jobject_type:
01275               env->SetStaticObjectField(clazz, fieldID, val.l);
01276               break;
01277        case jboolean_type:
01278               env->SetStaticBooleanField(clazz, fieldID, val.z);
01279               break;
01280        case jbyte_type:
01281               env->SetStaticByteField(clazz, fieldID, val.b);
01282               break;
01283        case jchar_type:
01284               env->SetStaticCharField(clazz, fieldID, val.c);
01285               break;
01286        case jshort_type:
01287               env->SetStaticShortField(clazz, fieldID, val.s);
01288               break;
01289        case jint_type:
01290               env->SetStaticIntField(clazz, fieldID, val.i);
01291               break;
01292        case jlong_type:
01293               env->SetStaticLongField(clazz, fieldID, val.j);
01294               break;
01295        case jfloat_type:
01296               env->SetStaticFloatField(clazz, fieldID, val.f);
01297               break;
01298        case jdouble_type:
01299               env->SetStaticDoubleField(clazz, fieldID, val.d);
01300               break;
01301        }
01302        }
01303 };
01304 
01305 NS_IMETHODIMP CSecureEnv::SetStaticField(/*[in]*/  jni_type type,
01306                                           /*[in]*/ jclass clazz, 
01307                                           /*[in]*/ jfieldID fieldID,
01308                                           /*[in]*/ jvalue val,
01309                                           /*[in]*/ nsISecurityContext* ctx)
01310 {
01311     if (mJavaEnv == NULL || clazz == NULL || fieldID == NULL)
01312         return NS_ERROR_NULL_POINTER;
01313 
01314 #if PROXY_JNI_CALLS
01315        // Set static field on Java side
01316        SetStaticFieldMessage msg(type, clazz, fieldID, val);
01317        sendMessageToJava(&msg);
01318 #else
01319        JNIEnv* env = mJavaEnv;
01320        switch (type) {
01321        case jobject_type:
01322               env->SetStaticObjectField(clazz, fieldID, val.l);
01323               break;
01324        case jboolean_type:
01325               env->SetStaticBooleanField(clazz, fieldID, val.z);
01326               break;
01327        case jbyte_type:
01328               env->SetStaticByteField(clazz, fieldID, val.b);
01329               break;
01330        case jchar_type:
01331               env->SetStaticCharField(clazz, fieldID, val.c);
01332               break;
01333        case jshort_type:
01334               env->SetStaticShortField(clazz, fieldID, val.s);
01335               break;
01336        case jint_type:
01337               env->SetStaticIntField(clazz, fieldID, val.i);
01338               break;
01339        case jlong_type:
01340               env->SetStaticLongField(clazz, fieldID, val.j);
01341               break;
01342        case jfloat_type:
01343               env->SetStaticFloatField(clazz, fieldID, val.f);
01344               break;
01345        case jdouble_type:
01346               env->SetStaticDoubleField(clazz, fieldID, val.d);
01347               break;
01348        }
01349 #endif
01350 
01351        return NS_OK;
01352 }
01353 
01354 
01355 NS_IMETHODIMP CSecureEnv::GetVersion(/*[out]*/ jint* version) 
01356 {
01357     if (mJavaEnv == NULL || version == NULL)
01358         return NS_ERROR_NULL_POINTER;
01359     
01360        JNIEnv* env = mJavaEnv;
01361        *version = env->GetVersion();
01362 
01363     return NS_OK;
01364 }
01365 
01369 class DefineClassMessage : public JavaMessage {
01370        const char* name;
01371        jobject loader;
01372        const jbyte *buf;
01373        jsize len;
01374        jclass* clazz;
01375 public:
01376        DefineClassMessage(const char* name, jobject loader, const jbyte *buf, jsize len, jclass* clazz)
01377        {
01378               this->name = name;
01379               this->loader = loader;
01380               this->buf = buf;
01381               this->len = len;
01382               this->clazz = clazz;
01383        }
01384        
01385        virtual void execute(JNIEnv* env)
01386        {
01387        *clazz = env->DefineClass(name, loader, buf, len);
01388        }
01389 };
01390 
01391 NS_IMETHODIMP CSecureEnv::DefineClass(/*[in]*/  const char* name,
01392                                        /*[in]*/  jobject loader,
01393                                        /*[in]*/  const jbyte *buf,
01394                                        /*[in]*/  jsize len,
01395                                        /*[out]*/ jclass* clazz) 
01396 {
01397     if (mJavaEnv == NULL || clazz == NULL)
01398         return NS_ERROR_NULL_POINTER;
01399 
01400 #if PROXY_JNI_CALLS
01401     DefineClassMessage msg(name, loader, buf, len, clazz);
01402     sendMessageToJava(&msg);
01403 #else
01404     *clazz = mJavaEnv->DefineClass(name, loader, buf, len);
01405 #endif
01406 
01407     return NS_OK;
01408 }
01409 
01413 class FindClassMessage : public JavaMessage {
01414        const char* name;
01415        jclass* result;
01416 public:
01417        FindClassMessage(const char* name, jclass* result)
01418        {
01419               this->name = name;
01420               this->result = result;
01421        }
01422 
01423        virtual void execute(JNIEnv* env)
01424        {
01425               *result = env->FindClass(name);
01426 #if LOCAL_REFS_ARE_GLOBAL
01427         *result = (jclass) ToGlobalRef(env, *result);
01428 #endif
01429        }
01430 };
01431 
01432 NS_IMETHODIMP CSecureEnv::FindClass(/*[in]*/  const char* name, 
01433                                      /*[out]*/ jclass* clazz) 
01434 {
01435     if (clazz == NULL)
01436         return NS_ERROR_NULL_POINTER;
01437 
01438 #if PROXY_JNI_CALLS
01439        FindClassMessage msg(name, clazz);
01440        sendMessageToJava(&msg);
01441 #else
01442        *clazz = mJavaEnv->FindClass(name);
01443 #endif
01444 
01445     return NS_OK;
01446 }
01447 
01451 class GetSuperclassMessage : public JavaMessage {
01452        jclass sub;
01453        jclass* super;
01454 public:
01455        GetSuperclassMessage(jclass sub, jclass* super)
01456        {
01457               this->sub = sub;
01458               this->super = super;
01459        }
01460 
01461        virtual void execute(JNIEnv* env)
01462        {
01463        *super = env->GetSuperclass(sub);
01464        }
01465 };
01466 
01467 NS_IMETHODIMP CSecureEnv::GetSuperclass(/*[in]*/  jclass sub,
01468                                          /*[out]*/ jclass* super) 
01469 {
01470     if (mJavaEnv == NULL || super == NULL)
01471         return NS_ERROR_NULL_POINTER;
01472 
01473 #if PROXY_JNI_CALLS
01474        GetSuperclassMessage msg(sub, super);
01475        sendMessageToJava(&msg);
01476 #else
01477        *super = mJavaEnv->GetSuperclass(sub);
01478 #endif
01479 
01480     return NS_OK;
01481 }
01482 
01483 
01484 class IsAssignableFromMessage : public JavaMessage {
01485     jclass sub;
01486     jclass super;
01487     jboolean* result;
01488 public:
01489        IsAssignableFromMessage(jclass sub, jclass super, jboolean* result)
01490        {
01491               this->sub = sub;
01492               this->super = super;
01493               this->result = result;
01494        }
01495 
01496        virtual void execute(JNIEnv* env)
01497        {
01498         *result = env->IsAssignableFrom(sub, super);
01499        }
01500 };
01501 
01502 NS_IMETHODIMP CSecureEnv::IsAssignableFrom(/*[in]*/  jclass sub,
01503                                             /*[in]*/  jclass super,
01504                                             /*[out]*/ jboolean* result) 
01505 {
01506     if (mJavaEnv == NULL || result == NULL)
01507         return NS_ERROR_NULL_POINTER;
01508 
01509 #if PROXY_JNI_CALLS    
01510        IsAssignableFromMessage msg(sub, super, result);
01511        sendMessageToJava(&msg);
01512 #else
01513        // JNIEnv* env = mSession->getCurrentEnv();
01514        *result = mJavaEnv->IsAssignableFrom(sub, super);
01515 #endif
01516 
01517     return NS_OK;
01518 }
01519 
01520 
01521 class ThrowMessage : public JavaMessage {
01522     jthrowable obj;
01523     jint* result;
01524 public:
01525        ThrowMessage(jthrowable obj, jint* result)
01526        {
01527               this->obj = obj;
01528               this->result = result;
01529        }
01530 
01531        virtual void execute(JNIEnv* env)
01532        {
01533         *result = env->Throw(obj);
01534        }
01535 };
01536 
01537 NS_IMETHODIMP CSecureEnv::Throw(/*[in]*/  jthrowable obj,
01538                                  /*[out]*/ jint* result) 
01539 {
01540        if (mJavaEnv == NULL || result == NULL)
01541         return NS_ERROR_NULL_POINTER;
01542     
01543 #if PROXY_JNI_CALLS    
01544        ThrowMessage msg(obj, result);
01545        sendMessageToJava(&msg);
01546 #else
01547     *result = mJavaEnv->Throw(obj);
01548 #endif
01549 
01550     return NS_OK;
01551 }
01552 
01553 class ThrowNewMessage : public JavaMessage {
01554     jclass clazz;
01555     const char* message;
01556     jint* result;
01557 public:
01558        ThrowNewMessage(jclass clazz, const char* message, jint* result)
01559        {
01560               this->clazz = clazz;
01561               this->message = message;
01562               this->result = result;
01563        }
01564 
01565        virtual void execute(JNIEnv* env)
01566        {
01567         *result = env->ThrowNew(clazz, message);
01568        }
01569 };
01570 
01571 NS_IMETHODIMP CSecureEnv::ThrowNew(/*[in]*/  jclass clazz,
01572                                     /*[in]*/  const char *message,
01573                                     /*[out]*/ jint* result) 
01574 {
01575     if (mJavaEnv == NULL || result == NULL)
01576         return NS_ERROR_NULL_POINTER;
01577     
01578 #if PROXY_JNI_CALLS    
01579        ThrowNewMessage msg(clazz, message, result);
01580        sendMessageToJava(&msg);
01581 #else
01582     *result = mJavaEnv->ThrowNew(clazz, msg);
01583 #endif
01584 
01585     return NS_OK;
01586 }
01587 
01588 
01589 class ExceptionOccurredMessage : public JavaMessage {
01590     CSecureEnv* secureEnv;
01591     jthrowable* result;
01592 public:
01593        ExceptionOccurredMessage(CSecureEnv* secureEnv, jthrowable* result)
01594        {
01595            this->secureEnv = secureEnv;
01596               this->result = result;
01597        }
01598 
01599        virtual void execute(JNIEnv* env)
01600        {
01601         *result = secureEnv->getPendingException(env);
01602 #if LOCAL_REFS_ARE_GLOBAL
01603         *result = (jthrowable) ToGlobalRef(env, *result);
01604 #endif
01605        }
01606 };
01607 
01608 NS_IMETHODIMP CSecureEnv::ExceptionOccurred(/*[out]*/ jthrowable* result)
01609 {
01610        if (mJavaEnv == NULL || result == NULL)
01611               return NS_ERROR_NULL_POINTER;
01612     
01613 #if PROXY_JNI_CALLS
01614        ExceptionOccurredMessage msg(this, result);
01615        sendMessageToJava(&msg);
01616 #else
01617     *result = mJavaEnv->ExceptionOccurred();
01618 #endif
01619 
01620     return NS_OK;
01621 }
01622 
01623 NS_IMETHODIMP CSecureEnv::ExceptionDescribe(void)
01624 {
01625        if (mJavaEnv == NULL)
01626               return NS_ERROR_NULL_POINTER;
01627 
01628 #if PROXY_JNI_CALLS    
01629        class ExceptionDescribeMessage : public JavaMessage {
01630     public:
01631        virtual void execute(JNIEnv* env) { env->ExceptionDescribe(); }
01632     } msg;
01633        sendMessageToJava(&msg);
01634 #else
01635     mJavaEnv->ExceptionDescribe();
01636 #endif
01637 
01638     return NS_OK;
01639 }
01640 
01641 class ExceptionClearMessage : public JavaMessage {
01642     CSecureEnv* secureEnv;
01643 public:
01644     ExceptionClearMessage(CSecureEnv* secureEnv)
01645     {
01646         this->secureEnv = secureEnv;
01647     }
01648        virtual void execute(JNIEnv* env) { secureEnv->clearPendingException(env); }
01649 };
01650 
01651 NS_IMETHODIMP CSecureEnv::ExceptionClear(void)
01652 {
01653 #if PROXY_JNI_CALLS
01654     ExceptionClearMessage msg(this); 
01655        sendMessageToJava(&msg);
01656 #else
01657     mJavaEnv->ExceptionClear();
01658 #endif
01659 
01660     return NS_OK;
01661 }
01662 
01663 
01664 NS_IMETHODIMP CSecureEnv::FatalError(/*[in]*/ const char* msg)
01665 {
01666     mJavaEnv->FatalError(msg);
01667     return NS_OK;
01668 }
01669 
01670 
01675 class NewGlobalRefMessage : public JavaMessage {
01676        jobject localRef;
01677        jobject* result;
01678 public:
01679        NewGlobalRefMessage(jobject localRef, jobject* result)
01680        {
01681               this->localRef = localRef;
01682               this->result = result;
01683        }
01684 
01685        virtual void execute(JNIEnv* env)
01686        {
01687               *result = env->NewGlobalRef(localRef);
01688        }
01689 };
01690 
01691 NS_IMETHODIMP CSecureEnv::NewGlobalRef(/*[in]*/  jobject localRef, 
01692                                         /*[out]*/ jobject* result)
01693 {
01694     if (result == NULL)
01695         return NS_ERROR_NULL_POINTER;
01696 
01697 #if PROXY_JNI_CALLS
01698     NewGlobalRefMessage msg(localRef, result);
01699        sendMessageToJava(&msg);
01700 #else
01701        *result = mJavaEnv->NewGlobalRef(localRef);
01702 #endif
01703 
01704     return NS_OK;
01705 }
01706 
01711 NS_IMETHODIMP CSecureEnv::DeleteGlobalRef(/*[in]*/ jobject globalRef) 
01712 {
01713     mJavaEnv->DeleteGlobalRef(globalRef);
01714     return NS_OK;
01715 }
01716 
01720 class DeleteLocalRefMessage : public JavaMessage {
01721        jobject localRef;
01722 public:
01723        DeleteLocalRefMessage(jobject localRef)
01724        {
01725               this->localRef = localRef;
01726        }
01727 
01728        virtual void execute(JNIEnv* env)
01729        {
01730 #if LOCAL_REFS_ARE_GLOBAL
01731               env->DeleteGlobalRef(localRef);
01732 #else
01733               env->DeleteLocalRef(localRef);
01734 #endif
01735        }
01736 };
01737 
01738 NS_IMETHODIMP CSecureEnv::DeleteLocalRef(/*[in]*/ jobject localRef)
01739 {
01740 #if PROXY_JNI_CALLS
01741     DeleteLocalRefMessage msg(localRef);
01742        sendMessageToJava(&msg);
01743 #else
01744     mJavaEnv->DeleteLocalRef(localRef);
01745 #endif
01746     return NS_OK;
01747 }
01748 
01749 class IsSameObjectMessage : public JavaMessage {
01750        jobject obj1;
01751        jobject obj2;
01752        jboolean* result;
01753 public:
01754        IsSameObjectMessage(jobject obj1, jobject obj2, jboolean* result)
01755        {
01756               this->obj1 = obj1;
01757               this->obj2 = obj2;
01758               this->result = result;
01759        }
01760 
01761        virtual void execute(JNIEnv* env)
01762        {
01763               *result = env->IsSameObject(obj1, obj2);
01764        }
01765 };
01766 
01767 NS_IMETHODIMP CSecureEnv::IsSameObject(/*[in]*/  jobject obj1,
01768                                         /*[in]*/  jobject obj2,
01769                                         /*[out]*/ jboolean* result) 
01770 {
01771     if (mJavaEnv == NULL || result == NULL)
01772         return NS_ERROR_NULL_POINTER;
01773     
01774 #if PROXY_JNI_CALLS
01775     IsSameObjectMessage msg(obj1, obj2, result);
01776        sendMessageToJava(&msg);
01777 #else
01778     *result = mJavaEnv->IsSameObject(obj1, obj2);
01779 #endif
01780 
01781     return NS_OK;
01782 }
01783 
01784 
01785 class AllocObjectMessage : public JavaMessage {
01786        jclass clazz;
01787        jobject* result;
01788 public:
01789        AllocObjectMessage(jclass clazz, jobject* result)
01790        {
01791               this->clazz = clazz;
01792               this->result = result;
01793        }
01794 
01795        virtual void execute(JNIEnv* env)
01796        {
01797               *result = env->AllocObject(clazz);
01798 #if LOCAL_REFS_ARE_GLOBAL
01799         *result = ToGlobalRef(env, *result);
01800 #endif
01801        }
01802 };
01803 
01804 NS_IMETHODIMP CSecureEnv::AllocObject(/*[in]*/  jclass clazz,
01805                                       /*[out]*/ jobject* result) 
01806 {
01807     if (mJavaEnv == NULL || result == NULL)
01808         return NS_ERROR_NULL_POINTER;
01809     
01810 #if PROXY_JNI_CALLS
01811     AllocObjectMessage msg(clazz, result);
01812        sendMessageToJava(&msg);
01813 #else
01814     *result = mJavaEnv->AllocObject(clazz);
01815 #endif
01816 
01817     return NS_OK;
01818 }
01819 
01820 class GetObjectClassMessage : public JavaMessage {
01821     jobject obj;
01822        jclass* result;
01823 public:
01824        GetObjectClassMessage(jobject obj, jclass* result)
01825        {
01826               this->obj = obj;
01827               this->result = result;
01828        }
01829 
01830        virtual void execute(JNIEnv* env)
01831        {
01832               *result = env->GetObjectClass(obj);
01833 #if LOCAL_REFS_ARE_GLOBAL
01834         *result = (jclass) ToGlobalRef(env, *result);
01835 #endif
01836        }
01837 };
01838 
01839 NS_IMETHODIMP CSecureEnv::GetObjectClass(/*[in]*/  jobject obj,
01840                                           /*[out]*/ jclass* result) 
01841 {
01842     if (mJavaEnv == NULL || result == NULL)
01843         return NS_ERROR_NULL_POINTER;
01844     
01845 #if PROXY_JNI_CALLS
01846     GetObjectClassMessage msg(obj, result);
01847        sendMessageToJava(&msg);
01848 #else
01849     *result = mJavaEnv->GetObjectClass(obj);
01850 #endif
01851 
01852     return NS_OK;
01853 }
01854 
01855 
01856 class IsInstanceOfMessage : public JavaMessage {
01857     jobject obj;
01858     jclass clazz;
01859        jboolean* result;
01860 public:
01861        IsInstanceOfMessage(jobject obj, jclass clazz, jboolean* result)
01862        {
01863               this->obj = obj;
01864               this->clazz = clazz;
01865               this->result = result;
01866        }
01867 
01868        virtual void execute(JNIEnv* env)
01869        {
01870               *result = env->IsInstanceOf(obj, clazz);
01871        }
01872 };
01873 
01874 NS_IMETHODIMP CSecureEnv::IsInstanceOf(/*[in]*/  jobject obj,
01875                                         /*[in]*/  jclass clazz,
01876                                         /*[out]*/ jboolean* result) 
01877 {
01878     if (mJavaEnv == NULL || result == NULL)
01879         return NS_ERROR_NULL_POINTER;
01880     
01881 #if PROXY_JNI_CALLS
01882     IsInstanceOfMessage msg(obj, clazz, result);
01883        sendMessageToJava(&msg);
01884 #else
01885     *result = mJavaEnv->IsInstanceOf(obj, clazz);
01886 #endif
01887 
01888     return NS_OK;
01889 }
01890 
01891 class GetMethodIDMessage : public JavaMessage {
01892     jclass clazz;
01893     const char* name;
01894     const char* sig;
01895     jboolean isStatic;
01896        jmethodID* result;
01897 public:
01898        GetMethodIDMessage(jclass clazz, const char* name, const char* sig,
01899                           jboolean isStatic, jmethodID* result)
01900        {
01901               this->clazz = clazz;
01902               this->name = name;
01903               this->sig = sig;
01904               this->isStatic = isStatic;
01905               this->result = result;
01906        }
01907 
01908        virtual void execute(JNIEnv* env)
01909        {
01910               *result = (isStatic ? env->GetStaticMethodID(clazz, name, sig)
01911                                   : env->GetMethodID(clazz, name, sig));
01912        }
01913 };
01914 
01915 class GetFieldIDMessage : public JavaMessage {
01916     jclass clazz;
01917     const char* name;
01918     const char* sig;
01919     jboolean isStatic;
01920        jfieldID* result;
01921 public:
01922        GetFieldIDMessage(jclass clazz, const char* name, const char* sig,
01923                           jboolean isStatic, jfieldID* result)
01924        {
01925               this->clazz = clazz;
01926               this->name = name;
01927               this->sig = sig;
01928               this->isStatic = isStatic;
01929               this->result = result;
01930        }
01931 
01932        virtual void execute(JNIEnv* env)
01933        {
01934               *result = (isStatic ? env->GetStaticFieldID(clazz, name, sig)
01935                                   : env->GetFieldID(clazz, name, sig));
01936        }
01937 };
01938 
01939 NS_IMETHODIMP CSecureEnv::GetMethodID(/*[in]*/  jclass clazz, 
01940                                        /*[in]*/  const char* name,
01941                                        /*[in]*/  const char* sig,
01942                                        /*[out]*/ jmethodID* result) 
01943 {
01944     if (result == NULL)
01945         return NS_ERROR_NULL_POINTER;
01946 
01947 #if PROXY_JNI_CALLS
01948     GetMethodIDMessage msg(clazz, name, sig, JNI_FALSE, result);
01949        sendMessageToJava(&msg);
01950 #else
01951     *result = mJavaEnv->GetMethodID(clazz, name, sig);
01952 #endif
01953 
01954     return NS_OK;
01955 }
01956 
01957 
01958 NS_IMETHODIMP CSecureEnv::GetFieldID(/*[in]*/  jclass clazz, 
01959                                       /*[in]*/  const char* name,
01960                                       /*[in]*/  const char* sig,
01961                                       /*[out]*/ jfieldID* result) 
01962 {
01963     if (result == NULL)
01964         return NS_ERROR_NULL_POINTER;
01965     
01966 #if PROXY_JNI_CALLS
01967     GetFieldIDMessage msg(clazz, name, sig, JNI_FALSE, result);
01968        sendMessageToJava(&msg);
01969 #else
01970     *result = mJavaEnv->GetFieldID(clazz, name, sig);
01971 #endif
01972 
01973     return NS_OK;
01974 }
01975 
01976 
01977 NS_IMETHODIMP CSecureEnv::GetStaticMethodID(/*[in]*/  jclass clazz, 
01978                                              /*[in]*/  const char* name,
01979                                              /*[in]*/  const char* sig,
01980                                              /*[out]*/ jmethodID* result)
01981 {
01982     if (result == NULL)
01983         return NS_ERROR_NULL_POINTER;
01984     
01985 #if PROXY_JNI_CALLS
01986     GetMethodIDMessage msg(clazz, name, sig, JNI_TRUE, result);
01987        sendMessageToJava(&msg);
01988 #else
01989     *result = mJavaEnv->GetStaticMethodID(clazz, name, sig);
01990 #endif
01991 
01992     return NS_OK;
01993 }
01994 
01995 
01996 NS_IMETHODIMP CSecureEnv::GetStaticFieldID(/*[in]*/  jclass clazz, 
01997                                             /*[in]*/  const char* name,
01998                                             /*[in]*/  const char* sig,
01999                                             /*[out]*/ jfieldID* result) 
02000 {
02001     if (result == NULL)
02002         return NS_ERROR_NULL_POINTER;
02003     
02004 #if PROXY_JNI_CALLS
02005     GetFieldIDMessage msg(clazz, name, sig, JNI_TRUE, result);
02006        sendMessageToJava(&msg);
02007 #else
02008     *result = mJavaEnv->GetStaticFieldID(clazz, name, sig);
02009 #endif
02010 
02011     return NS_OK;
02012 }
02013 
02018 class NewStringMessage : public JavaMessage {
02019        const jchar* unicode;
02020        jsize len;
02021        jstring* result;
02022 public:
02023        NewStringMessage(const jchar* unicode, jsize len, jstring* result)
02024        {
02025               this->unicode = unicode;
02026               this->len = len;
02027               this->result = result;
02028        }
02029 
02030        virtual void execute(JNIEnv* env)
02031        {
02032        *result = env->NewString(unicode, len);
02033 #if LOCAL_REFS_ARE_GLOBAL
02034         *result = (jstring) ToGlobalRef(env, *result);
02035 #endif
02036        }
02037 };
02038 
02039 NS_IMETHODIMP CSecureEnv::NewString(/*[in]*/  const jchar* unicode,
02040                                      /*[in]*/  jsize len,
02041                                      /*[out]*/ jstring* result) 
02042 {
02043     if (result == NULL)
02044         return NS_ERROR_NULL_POINTER;
02045 
02046 #if PROXY_JNI_CALLS    
02047     NewStringMessage msg(unicode, len, result);
02048     sendMessageToJava(&msg);
02049 #else
02050        *result = mJavaEnv->NewString(unicode, len);
02051 #endif
02052 
02053     return NS_OK;
02054 }
02055 
02056 class GetStringLengthMessage : public JavaMessage {
02057        jstring str;
02058        jsize* result;
02059 public:
02060        GetStringLengthMessage(jstring str, jsize* result)
02061        {
02062               this->str = str;
02063               this->result = result;
02064        }
02065 
02066        virtual void execute(JNIEnv* env)
02067        {
02068        *result = env->GetStringLength(str);
02069        }
02070 };
02071 
02072 NS_IMETHODIMP CSecureEnv::GetStringLength(/*[in]*/  jstring str,
02073                                            /*[out]*/ jsize* result) 
02074 {
02075     if (mJavaEnv == NULL || result == NULL)
02076         return NS_ERROR_NULL_POINTER;
02077 
02078 #if PROXY_JNI_CALLS    
02079     GetStringLengthMessage msg(str, result);
02080     sendMessageToJava(&msg);
02081 #else
02082     *result = mJavaEnv->GetStringLength(str);
02083 #endif
02084 
02085     return NS_OK;
02086 }
02087 
02088 class GetStringCharsMessage : public JavaMessage {
02089        jstring str;
02090        jboolean* isCopy;
02091        const jchar** result;
02092 public:
02093        GetStringCharsMessage(jstring str, jboolean* isCopy, const jchar** result)
02094        {
02095               this->str = str;
02096               this->isCopy = isCopy;
02097               this->result = result;
02098        }
02099 
02100        virtual void execute(JNIEnv* env)
02101        {
02102        *result = env->GetStringChars(str, isCopy);
02103        }
02104 };
02105 
02106 NS_IMETHODIMP CSecureEnv::GetStringChars(/*[in]*/  jstring str,
02107                                           /*[in]*/  jboolean *isCopy,
02108                                           /*[out]*/ const jchar** result) 
02109 {
02110     if (mJavaEnv == NULL || result == NULL)
02111         return NS_ERROR_NULL_POINTER;
02112     
02113 #if PROXY_JNI_CALLS    
02114     GetStringCharsMessage msg(str, isCopy, result);
02115     sendMessageToJava(&msg);
02116 #else
02117     *result = mJavaEnv->GetStringChars(str, isCopy);
02118 #endif
02119 
02120     return NS_OK;
02121 }
02122 
02123 
02124 class ReleaseStringCharsMessage : public JavaMessage {
02125        jstring str;
02126        const jchar* chars;
02127 public:
02128        ReleaseStringCharsMessage(jstring str, const jchar* chars)
02129        {
02130               this->str = str;
02131               this->chars = chars;
02132        }
02133 
02134        virtual void execute(JNIEnv* env)
02135        {
02136        env->ReleaseStringChars(str, chars);
02137        }
02138 };
02139 
02140 NS_IMETHODIMP CSecureEnv::ReleaseStringChars(/*[in]*/  jstring str,
02141                                               /*[in]*/  const jchar *chars) 
02142 {
02143     if (mJavaEnv == NULL)
02144         return NS_ERROR_NULL_POINTER;
02145     
02146 #if PROXY_JNI_CALLS    
02147     ReleaseStringCharsMessage msg(str, chars);
02148     sendMessageToJava(&msg);
02149 #else
02150     mJavaEnv->ReleaseStringChars(str, chars);
02151 #endif
02152 
02153     return NS_OK;
02154 }
02155 
02156 class NewStringUTFMessage : public JavaMessage {
02157        const char *utf;
02158        jstring* result;
02159 public:
02160        NewStringUTFMessage(const char *utf, jstring* result)
02161        {
02162               this->utf = utf;
02163               this->result = result;
02164        }
02165 
02166        virtual void execute(JNIEnv* env)
02167        {
02168        *result = env->NewStringUTF(utf);
02169 #if LOCAL_REFS_ARE_GLOBAL
02170         *result = (jstring) ToGlobalRef(env, *result);
02171 #endif
02172        }
02173 };
02174 
02175 NS_IMETHODIMP CSecureEnv::NewStringUTF(/*[in]*/  const char *utf,
02176                                         /*[out]*/ jstring* result) 
02177 {
02178     if (mJavaEnv == NULL || result == NULL)
02179         return NS_ERROR_NULL_POINTER;
02180     
02181 #if PROXY_JNI_CALLS    
02182        NewStringUTFMessage msg(utf, result);
02183     sendMessageToJava(&msg);
02184 #else
02185        *result = mJavaEnv->NewStringUTF(utf);
02186 #endif
02187 
02188     return NS_OK;
02189 }
02190 
02191 
02192 class GetStringUTFLengthMessage : public JavaMessage {
02193        jstring str;
02194        jsize* result;
02195 public:
02196        GetStringUTFLengthMessage(jstring str, jsize* result)
02197        {
02198               this->str = str;
02199               this->result = result;
02200        }
02201 
02202        virtual void execute(JNIEnv* env)
02203        {
02204        *result = env->GetStringUTFLength(str);
02205        }
02206 };
02207 
02208 NS_IMETHODIMP CSecureEnv::GetStringUTFLength(/*[in]*/  jstring str,
02209                                               /*[out]*/ jsize* result) 
02210 {
02211     if (mJavaEnv == NULL || result == NULL)
02212         return NS_ERROR_NULL_POINTER;
02213     
02214 #if PROXY_JNI_CALLS    
02215        GetStringUTFLengthMessage msg(str, result);
02216     sendMessageToJava(&msg);
02217 #else
02218     *result = mJavaEnv->GetStringUTFLength(str);
02219 #endif
02220 
02221     return NS_OK;
02222 }
02223 
02224     
02225 class GetStringUTFCharsMessage : public JavaMessage {
02226        jstring str;
02227        jboolean* isCopy;
02228        const char** result;
02229 public:
02230        GetStringUTFCharsMessage(jstring str, jboolean* isCopy, const char** result)
02231        {
02232               this->str = str;
02233               this->isCopy = isCopy;
02234               this->result = result;
02235        }
02236 
02237        virtual void execute(JNIEnv* env)
02238        {
02239        *result = env->GetStringUTFChars(str, isCopy);
02240        }
02241 };
02242 
02243 NS_IMETHODIMP CSecureEnv::GetStringUTFChars(/*[in]*/  jstring str,
02244                                              /*[in]*/  jboolean *isCopy,
02245                                              /*[out]*/ const char** result) 
02246 {
02247     if (mJavaEnv == NULL || result == NULL)
02248         return NS_ERROR_NULL_POINTER;
02249     
02250 #if PROXY_JNI_CALLS    
02251        GetStringUTFCharsMessage msg(str, isCopy, result);
02252     sendMessageToJava(&msg);
02253 #else
02254     *result = mJavaEnv->GetStringUTFChars(str, isCopy);
02255 #endif
02256 
02257     return NS_OK;
02258 }
02259 
02260 
02261 class ReleaseStringUTFCharsMessage : public JavaMessage {
02262        jstring str;
02263        const char* chars;
02264 public:
02265        ReleaseStringUTFCharsMessage(jstring str, const char* chars)
02266        {
02267               this->str = str;
02268               this->chars = chars;
02269        }
02270 
02271        virtual void execute(JNIEnv* env)
02272        {
02273        env->ReleaseStringUTFChars(str, chars);
02274        }
02275 };
02276 
02277 NS_IMETHODIMP CSecureEnv::ReleaseStringUTFChars(/*[in]*/  jstring str,
02278                                                  /*[in]*/  const char *chars) 
02279 {
02280     if (mJavaEnv == NULL)
02281         return NS_ERROR_NULL_POINTER;
02282     
02283 #if PROXY_JNI_CALLS    
02284        ReleaseStringUTFCharsMessage msg(str, chars);
02285     sendMessageToJava(&msg);
02286 #else
02287     mJavaEnv->ReleaseStringUTFChars(str, chars);
02288 #endif
02289 
02290     return NS_OK;
02291 }
02292 
02293 
02294 class GetArrayLengthMessage : public JavaMessage {
02295        jarray array;
02296        jsize* result;
02297 public:
02298        GetArrayLengthMessage(jarray array, jsize* result)
02299        {
02300               this->array = array;
02301               this->result = result;
02302        }
02303 
02304        virtual void execute(JNIEnv* env)
02305        {
02306        *result = env->GetArrayLength(array);
02307        }
02308 };
02309 
02310 NS_IMETHODIMP CSecureEnv::GetArrayLength(/*[in]*/  jarray array,
02311                                          /*[out]*/ jsize* result) 
02312 {
02313     if (mJavaEnv == NULL || result == NULL)
02314         return NS_ERROR_NULL_POINTER;
02315     
02316 #if PROXY_JNI_CALLS    
02317        GetArrayLengthMessage msg(array, result);
02318     sendMessageToJava(&msg);
02319 #else
02320     *result = mJavaEnv->GetArrayLength(array);
02321 #endif
02322 
02323     return NS_OK;
02324 }
02325 
02326 class NewObjectArrayMessage : public JavaMessage {
02327     jsize len;
02328        jclass clazz;
02329        jobject init;
02330        jobjectArray* result;
02331 public:
02332        NewObjectArrayMessage(jsize len, jclass clazz, jobject init, jobjectArray* result)
02333        {
02334            this->len = len;
02335               this->clazz = clazz;
02336               this->init = init;
02337               this->result = result;
02338        }
02339 
02340        virtual void execute(JNIEnv* env)
02341        {
02342               *result = env->NewObjectArray(len, clazz, init);
02343 #if LOCAL_REFS_ARE_GLOBAL
02344         *result = (jobjectArray) ToGlobalRef(env, *result);
02345 #endif
02346        }
02347 };
02348 
02349 NS_IMETHODIMP CSecureEnv::NewObjectArray(/*[in]*/  jsize len,
02350                                                                        /*[in]*/  jclass clazz,
02351                                                         /*[in]*/  jobject init,
02352                                                         /*[out]*/ jobjectArray* result)
02353 {
02354     if (mJavaEnv == NULL || result == NULL)
02355         return NS_ERROR_NULL_POINTER;
02356 
02357 #if PROXY_JNI_CALLS    
02358        NewObjectArrayMessage msg(len, clazz, init, result);
02359     sendMessageToJava(&msg);
02360 #else
02361     *result = mJavaEnv->NewObjectArray(len, clazz, init);
02362 #endif
02363 
02364     return NS_OK;
02365 }
02366 
02367 class GetObjectArrayElementMessage : public JavaMessage {
02368        jobjectArray array;
02369        jsize index;
02370        jobject* result;
02371 public:
02372        GetObjectArrayElementMessage(jobjectArray array, jsize index, jobject* result)
02373        {
02374               this->array = array;
02375               this->index = index;
02376               this->result = result;
02377        }
02378        
02379        virtual void execute(JNIEnv* env)
02380        {
02381         *result = env->GetObjectArrayElement(array, index);
02382 #if LOCAL_REFS_ARE_GLOBAL
02383         *result = ToGlobalRef(env, *result);
02384 #endif
02385        }
02386 };
02387 
02388 NS_IMETHODIMP CSecureEnv::GetObjectArrayElement(/*[in]*/  jobjectArray array,
02389                                                  /*[in]*/  jsize index,
02390                                                  /*[out]*/ jobject* result)
02391 {
02392     if (mJavaEnv == NULL || result == NULL)
02393         return NS_ERROR_NULL_POINTER;
02394 
02395 #if PROXY_JNI_CALLS    
02396        GetObjectArrayElementMessage msg(array, index, result);
02397     sendMessageToJava(&msg);
02398 #else
02399     *result = mJavaEnv->GetObjectArrayElement(array, index);
02400 #endif
02401 
02402     return NS_OK;
02403 }
02404 
02405 
02406 class SetObjectArrayElementMessage : public JavaMessage {
02407        jobjectArray array;
02408        jsize index;
02409        jobject val;
02410 public:
02411        SetObjectArrayElementMessage(jobjectArray array, jsize index, jobject val)
02412        {
02413               this->array = array;
02414               this->index = index;
02415               this->val = val;
02416        }
02417        
02418        virtual void execute(JNIEnv* env)
02419        {
02420         env->SetObjectArrayElement(array, index, val);
02421        }
02422 };
02423 
02424 NS_IMETHODIMP CSecureEnv::SetObjectArrayElement(/*[in]*/  jobjectArray array,
02425                                                  /*[in]*/  jsize index,
02426                                                  /*[in]*/  jobject val) 
02427 {
02428     if (mJavaEnv == NULL)
02429         return NS_ERROR_NULL_POINTER;
02430 
02431 #if PROXY_JNI_CALLS    
02432        SetObjectArrayElementMessage msg(array, index, val);
02433     sendMessageToJava(&msg);
02434 #else
02435     mJavaEnv->SetObjectArrayElement(array, index, val);
02436 #endif
02437 
02438     return NS_OK;
02439 }
02440 
02441 class NewArrayMessage : public JavaMessage {
02442        jni_type element_type;
02443        jsize len;
02444        jarray* result;
02445 public:
02446        NewArrayMessage(jni_type element_type, jsize len, jarray* result)
02447        {
02448               this->element_type = element_type;
02449               this->len = len;
02450               this->result = result;
02451        }
02452 
02453        virtual void execute(JNIEnv* env)
02454        {
02455         switch (element_type) {
02456         case jboolean_type:
02457             *result = env->NewBooleanArray(len);
02458             break;
02459         case jbyte_type:
02460             *result = env->NewByteArray(len);
02461             break;
02462         case jchar_type:
02463             *result = env->NewCharArray(len);
02464             break;
02465         case jshort_type:
02466             *result = env->NewShortArray(len);
02467             break;
02468         case jint_type:
02469             *result = env->NewIntArray(len);
02470             break;
02471         case jlong_type:
02472             *result = env->NewLongArray(len);
02473             break;
02474         case jfloat_type:
02475             *result = env->NewFloatArray(len);
02476             break;
02477         case jdouble_type:
02478             *result = env->NewDoubleArray(len);
02479             break;
02480         default:
02481             *result = NULL;
02482         }
02483 #if LOCAL_REFS_ARE_GLOBAL
02484         *result = (jarray) ToGlobalRef(env, *result);
02485 #endif
02486        }
02487 };
02488 
02489 NS_IMETHODIMP CSecureEnv::NewArray(/*[in]*/ jni_type element_type,
02490                                           /*[in]*/  jsize len,
02491                                           /*[out]*/ jarray* result) 
02492 {
02493     if (mJavaEnv == NULL || result == NULL)
02494         return NS_ERROR_NULL_POINTER;
02495 
02496 #if PROXY_JNI_CALLS    
02497        NewArrayMessage msg(element_type, len, result);
02498     sendMessageToJava(&msg);
02499 #else
02500     JNIEnv* env = mJavaEnv;
02501     switch (element_type) {
02502     case jboolean_type:
02503         *result = env->NewBooleanArray(len);
02504         break;
02505     case jbyte_type:
02506         *result = env->NewByteArray(len);
02507         break;
02508     case jchar_type:
02509         *result = env->NewCharArray(len);
02510         break;
02511     case jshort_type:
02512         *result = env->NewShortArray(len);
02513         break;
02514     case jint_type:
02515         *result = env->NewIntArray(len);
02516         break;
02517     case jlong_type:
02518         *result = env->NewLongArray(len);
02519         break;
02520     case jfloat_type:
02521         *result = env->NewFloatArray(len);
02522         break;
02523     case jdouble_type:
02524         *result = env->NewDoubleArray(len);
02525         break;
02526     default:
02527         *result = NULL;
02528     }
02529 #endif
02530 
02531     return NS_OK;
02532 }
02533 
02534 class GetArrayElementsMessage : public JavaMessage {
02535        jni_type element_type;
02536        jarray array;
02537        jboolean* isCopy;
02538        void* result;
02539 public:
02540        GetArrayElementsMessage(jni_type element_type, jarray array, jboolean* isCopy, void* result)
02541        {
02542               this->element_type = element_type;
02543               this->array = array;
02544               this->isCopy = isCopy;
02545               this->result = result;
02546        }
02547 
02548        virtual void execute(JNIEnv* env)
02549        {
02550         switch (element_type) {
02551        case jboolean_type:
02552            *(jboolean**) result = env->GetBooleanArrayElements((jbooleanArray)array, isCopy);
02553            break;
02554        case jbyte_type:
02555            *(jbyte**) result = env->GetByteArrayElements((jbyteArray)array, isCopy);
02556            break;
02557        case jchar_type:
02558            *(jchar**) result = env->GetCharArrayElements((jcharArray)array, isCopy);
02559            break;
02560        case jshort_type:
02561            * (jshort**) result = env->GetShortArrayElements((jshortArray)array, isCopy);
02562            break;
02563        case jint_type:
02564            * (jint**) result = env->GetIntArrayElements((jintArray)array, isCopy);
02565            break;
02566        case jlong_type:
02567            * (jlong**) result = env->GetLongArrayElements((jlongArray)array, isCopy);
02568            break;
02569        case jfloat_type:
02570            * (jfloat**) result = env->GetFloatArrayElements((jfloatArray)array, isCopy);
02571            break;
02572        case jdouble_type:
02573            * (jdouble**) result = env->GetDoubleArrayElements((jdoubleArray)array, isCopy);
02574            break;
02575        default:
02576            *(void**)result = NULL;
02577        }
02578        }
02579 };
02580 
02581 NS_IMETHODIMP CSecureEnv::GetArrayElements(/*[in]*/  jni_type element_type,
02582                                            /*[in]*/  jarray array,
02583                                            /*[in]*/  jboolean *isCopy,
02584                                            /*[out]*/ void* result)
02585 {
02586     if (mJavaEnv == NULL || result == NULL)
02587         return NS_ERROR_NULL_POINTER;
02588 
02589 #if PROXY_JNI_CALLS
02590     GetArrayElementsMessage msg(element_type, array, isCopy, result);
02591     sendMessageToJava(&msg);
02592 #else
02593     JNIEnv* env = mJavaEnv;
02594     switch (element_type) {
02595        case jboolean_type:
02596            *(jboolean**) result = env->GetBooleanArrayElements((jbooleanArray)array, isCopy);
02597            break;
02598        case jbyte_type:
02599            *(jbyte**) result = env->GetByteArrayElements((jbyteArray)array, isCopy);
02600            break;
02601        case jchar_type:
02602            *(jchar**) result = env->GetCharArrayElements((jcharArray)array, isCopy);
02603            break;
02604        case jshort_type:
02605            * (jshort**) result = env->GetShortArrayElements((jshortArray)array, isCopy);
02606            break;
02607        case jint_type:
02608            * (jint**) result = env->GetIntArrayElements((jintArray)array, isCopy);
02609            break;
02610        case jlong_type:
02611            * (jlong**) result = env->GetLongArrayElements((jlongArray)array, isCopy);
02612            break;
02613        case jfloat_type:
02614            * (jfloat**) result = env->GetFloatArrayElements((jfloatArray)array, isCopy);
02615            break;
02616        case jdouble_type:
02617            * (jdouble**) result = env->GetDoubleArrayElements((jdoubleArray)array, isCopy);
02618            break;
02619        default:
02620            *(void**)result = NULL;
02621        }
02622 #endif
02623 
02624     return NS_OK;
02625 }
02626 
02627 
02628 class ReleaseArrayElementsMessage : public JavaMessage {
02629        jni_type element_type;
02630        jarray array;
02631        void* elems;
02632        jint mode;
02633 public:
02634        ReleaseArrayElementsMessage(jni_type element_type, jarray array, void* elems, jint mode)
02635        {
02636               this->element_type = element_type;
02637               this->array = array;
02638               this->elems = elems;
02639               this->mode = mode;
02640        }
02641 
02642        virtual void execute(JNIEnv* env)
02643        {
02644        switch (element_type) {
02645        case jboolean_type:
02646               env->ReleaseBooleanArrayElements((jbooleanArray)array, (jboolean*)elems, mode);
02647               break;
02648        case jbyte_type:
02649               env->ReleaseByteArrayElements((jbyteArray)array, (jbyte*)elems, mode);
02650               break;
02651        case jchar_type:
02652               env->ReleaseCharArrayElements((jcharArray)array, (jchar*)elems, mode);
02653               break;
02654        case jshort_type:
02655               env->ReleaseShortArrayElements((jshortArray)array, (jshort*)elems, mode);
02656               break;
02657        case jint_type:
02658               env->ReleaseIntArrayElements((jintArray)array, (jint*)elems, mode);
02659               break;
02660        case jlong_type:
02661               env->ReleaseLongArrayElements((jlongArray)array, (jlong*)elems, mode);
02662               break;
02663        case jfloat_type:
02664               env->ReleaseFloatArrayElements((jfloatArray)array, (jfloat*)elems, mode);
02665               break;
02666        case jdouble_type:
02667               env->ReleaseDoubleArrayElements((jdoubleArray)array, (jdouble*)elems, mode);
02668               break;
02669        }
02670        }
02671 };
02672 
02673 NS_IMETHODIMP CSecureEnv::ReleaseArrayElements(/*[in]*/ jni_type element_type,
02674                                                 /*[in]*/ jarray array,
02675                                                 /*[in]*/ void *elems,
02676                                                 /*[in]*/ jint mode) 
02677 {
02678        if (mJavaEnv == NULL)
02679               return NS_ERROR_NULL_POINTER;
02680        
02681 #if PROXY_JNI_CALLS
02682     ReleaseArrayElementsMessage msg(element_type, array, elems, mode);
02683     sendMessageToJava(&msg);
02684 #else
02685        JNIEnv* env = mJavaEnv;
02686        switch (element_type) {
02687        case jboolean_type:
02688               env->ReleaseBooleanArrayElements((jbooleanArray)array, (jboolean*)elems, mode);
02689               break;
02690        case jbyte_type:
02691               env->ReleaseByteArrayElements((jbyteArray)array, (jbyte*)elems, mode);
02692               break;
02693        case jchar_type:
02694               env->ReleaseCharArrayElements((jcharArray)array, (jchar*)elems, mode);
02695               break;
02696        case jshort_type:
02697               env->ReleaseShortArrayElements((jshortArray)array, (jshort*)elems, mode);
02698               break;
02699        case jint_type:
02700               env->ReleaseIntArrayElements((jintArray)array, (jint*)elems, mode);
02701               break;
02702        case jlong_type:
02703               env->ReleaseLongArrayElements((jlongArray)array, (jlong*)elems, mode);
02704               break;
02705        case jfloat_type:
02706               env->ReleaseFloatArrayElements((jfloatArray)array, (jfloat*)elems, mode);
02707               break;
02708        case jdouble_type:
02709               env->ReleaseDoubleArrayElements((jdoubleArray)array, (jdouble*)elems, mode);
02710               break;
02711        }
02712 #endif
02713 
02714     return NS_OK;
02715 }
02716 
02717 class GetArrayRegionMessage : public JavaMessage {
02718        jni_type element_type;
02719        jarray array;
02720        jsize start;
02721        jsize len;
02722        void* buf;
02723 public:
02724        GetArrayRegionMessage(jni_type element_type, jarray array, jsize start, jsize len, void* buf)
02725        {
02726               this->element_type = element_type;
02727               this->array = array;
02728               this->start = start;
02729               this->len = len;
02730               this->buf = buf;
02731        }
02732 
02733        virtual void execute(JNIEnv* env)
02734        {
02735         switch (element_type) {
02736         case jboolean_type:
02737             env->GetBooleanArrayRegion((jbooleanArray)array, start, len, (jboolean*)buf);
02738             break;
02739         case jbyte_type:
02740             env->GetByteArrayRegion((jbyteArray)array, start, len, (jbyte*)buf);
02741             break;
02742         case jchar_type:
02743             env->GetCharArrayRegion((jcharArray)array, start, len, (jchar*)buf);
02744             break;
02745         case jshort_type:
02746             env->GetShortArrayRegion((jshortArray)array, start, len, (jshort*)buf);
02747             break;
02748         case jint_type:
02749             env->GetIntArrayRegion((jintArray)array, start, len, (jint*)buf);
02750             break;
02751         case jlong_type:
02752             env->GetLongArrayRegion((jlongArray)array, start, len, (jlong*)buf);
02753             break;
02754         case jfloat_type:
02755             env->GetFloatArrayRegion((jfloatArray)array, start, len, (jfloat*)buf);
02756             break;
02757         case jdouble_type:
02758             env->GetDoubleArrayRegion((jdoubleArray)array, start, len, (jdouble*)buf);
02759             break;
02760         }
02761        }
02762 };
02763 
02764 NS_IMETHODIMP CSecureEnv::GetArrayRegion(/*[in]*/  jni_type element_type,
02765                                          /*[in]*/  jarray array,
02766                                          /*[in]*/  jsize start,
02767                                          /*[in]*/  jsize len,
02768                                          /*[out]*/ void* buf)
02769 {
02770     if (mJavaEnv == NULL || buf == NULL)
02771         return NS_ERROR_NULL_POINTER;
02772 
02773 #if PROXY_JNI_CALLS
02774     GetArrayRegionMessage msg(element_type, array, start, len, buf);
02775     sendMessageToJava(&msg);
02776 #else
02777     JNIEnv* env = mJavaEnv;
02778     switch (element_type) {
02779     case jboolean_type:
02780         env->GetBooleanArrayRegion((jbooleanArray)array, start, len, (jboolean*)buf);
02781         break;
02782     case jbyte_type:
02783         env->GetByteArrayRegion((jbyteArray)array, start, len, (jbyte*)buf);
02784         break;
02785     case jchar_type:
02786         env->GetCharArrayRegion((jcharArray)array, start, len, (jchar*)buf);
02787         break;
02788     case jshort_type:
02789         env->GetShortArrayRegion((jshortArray)array, start, len, (jshort*)buf);
02790         break;
02791     case jint_type:
02792         env->GetIntArrayRegion((jintArray)array, start, len, (jint*)buf);
02793         break;
02794     case jlong_type:
02795         env->GetLongArrayRegion((jlongArray)array, start, len, (jlong*)buf);
02796         break;
02797     case jfloat_type:
02798         env->GetFloatArrayRegion((jfloatArray)array, start, len, (jfloat*)buf);
02799         break;
02800     case jdouble_type:
02801         env->GetDoubleArrayRegion((jdoubleArray)array, start, len, (jdouble*)buf);
02802         break;
02803     default:
02804         return NS_ERROR_FAILURE;
02805     }
02806 #endif
02807 
02808     return NS_OK;
02809 }
02810 
02811 
02812 class SetArrayRegionMessage : public JavaMessage {
02813        jni_type element_type;
02814        jarray array;
02815        jsize start;
02816        jsize len;
02817        void* buf;
02818 public:
02819        SetArrayRegionMessage(jni_type element_type, jarray array, jsize start, jsize len, void* buf)
02820        {
02821               this->element_type = element_type;
02822               this->array = array;
02823               this->start = start;
02824               this->len = len;
02825               this->buf = buf;
02826        }
02827 
02828        virtual void execute(JNIEnv* env)
02829        {
02830         switch (element_type) {
02831         case jboolean_type:
02832             env->SetBooleanArrayRegion((jbooleanArray)array, start, len, (jboolean*)buf);
02833             break;
02834         case jbyte_type:
02835             env->SetByteArrayRegion((jbyteArray)array, start, len, (jbyte*)buf);
02836             break;
02837         case jchar_type:
02838             env->SetCharArrayRegion((jcharArray)array, start, len, (jchar*)buf);
02839             break;
02840         case jshort_type:
02841             env->SetShortArrayRegion((jshortArray)array, start, len, (jshort*)buf);
02842             break;
02843         case jint_type:
02844             env->SetIntArrayRegion((jintArray)array, start, len, (jint*)buf);
02845             break;
02846         case jlong_type:
02847             env->SetLongArrayRegion((jlongArray)array, start, len, (jlong*)buf);
02848             break;
02849         case jfloat_type:
02850             env->SetFloatArrayRegion((jfloatArray)array, start, len, (jfloat*)buf);
02851             break;
02852         case jdouble_type:
02853             env->SetDoubleArrayRegion((jdoubleArray)array, start, len, (jdouble*)buf);
02854             break;
02855         }
02856        }
02857 };
02858 
02859 NS_IMETHODIMP CSecureEnv::SetArrayRegion(/*[in]*/  jni_type element_type,
02860                                          /*[in]*/  jarray array,
02861                                          /*[in]*/  jsize start,
02862                                          /*[in]*/  jsize len,
02863                                          /*[in]*/  void* buf)
02864 {
02865     if (mJavaEnv == NULL || buf == NULL)
02866         return NS_ERROR_NULL_POINTER;
02867 
02868 #if PROXY_JNI_CALLS
02869     SetArrayRegionMessage msg(element_type, array, start, len, buf);
02870     sendMessageToJava(&msg);
02871 #else
02872     JNIEnv* env = mJavaEnv;
02873     switch (type) {
02874     case jboolean_type:
02875         env->SetBooleanArrayRegion((jbooleanArray)array, start, len, (jboolean*)buf);
02876         break;
02877     case jbyte_type:
02878         env->SetByteArrayRegion((jbyteArray)array, start, len, (jbyte*)buf);
02879         break;
02880     case jchar_type:
02881         env->SetCharArrayRegion((jcharArray)array, start, len, (jchar*)buf);
02882         break;
02883     case jshort_type:
02884         env->SetShortArrayRegion((jshortArray)array, start, len, (jshort*)buf);
02885         break;
02886     case jint_type:
02887         env->SetIntArrayRegion((jintArray)array, start, len, (jint*)buf);
02888         break;
02889     case jlong_type:
02890         env->SetLongArrayRegion((jlongArray)array, start, len, (jlong*)buf);
02891         break;
02892     case jfloat_type:
02893         env->SetFloatArrayRegion((jfloatArray)array, start, len, (jfloat*)buf);
02894         break;
02895     case jdouble_type:
02896         env->SetDoubleArrayRegion((jdoubleArray)array, start, len, (jdouble*)buf);
02897         break;
02898     default:
02899         return NS_ERROR_FAILURE;
02900     }
02901 #endif
02902 
02903     return NS_OK;
02904 }
02905 
02906 
02907 class RegisterNativesMessage : public JavaMessage {
02908        jclass clazz;
02909        const JNINativeMethod *methods;
02910        jint nMethods;
02911        jint* result;
02912 public:
02913        RegisterNativesMessage(jclass clazz, const JNINativeMethod *methods, jint nMethods, jint* result)
02914        {
02915               this->clazz = clazz;
02916               this->methods = methods;
02917               this->nMethods = nMethods;
02918               this->result = result;
02919        }
02920        
02921        virtual void execute(JNIEnv* env)
02922        {
02923        *result = env->RegisterNatives(clazz, methods, nMethods);
02924        }
02925 };
02926 
02927 NS_IMETHODIMP CSecureEnv::RegisterNatives(/*[in]*/  jclass clazz,
02928                                            /*[in]*/  const JNINativeMethod *methods,
02929                                            /*[in]*/  jint nMethods,
02930                                            /*[out]*/ jint* result) 
02931 {
02932     if (mJavaEnv == NULL || result == NULL)
02933         return NS_ERROR_NULL_POINTER;
02934 
02935 #if PROXY_JNI_CALLS
02936     RegisterNativesMessage msg(clazz, methods, nMethods, result);
02937     sendMessageToJava(&msg);
02938 #else
02939     *result = mJavaEnv->RegisterNatives(clazz, methods, nMethods);
02940 #endif
02941 
02942     return NS_OK;
02943 }
02944 
02945 
02946 class UnregisterNativesMessage : public JavaMessage {
02947        jclass clazz;
02948        jint* result;
02949 public:
02950        UnregisterNativesMessage(jclass clazz, jint* result)
02951        {
02952               this->clazz = clazz;
02953               this->result = result;
02954        }
02955        
02956        virtual void execute(JNIEnv* env)
02957        {
02958        *result = env->UnregisterNatives(clazz);
02959        }
02960 };
02961 
02962 NS_IMETHODIMP CSecureEnv::UnregisterNatives(/*[in]*/  jclass clazz,
02963                                              /*[out]*/ jint* result) 
02964 {
02965     if (mJavaEnv == NULL || result == NULL)
02966         return NS_ERROR_NULL_POINTER;
02967 
02968 #if PROXY_JNI_CALLS
02969     UnregisterNativesMessage msg(clazz, result);
02970     sendMessageToJava(&msg);
02971 #else
02972     *result = mJavaEnv->UnregisterNatives(clazz);
02973 #endif
02974 
02975     return NS_OK;
02976 }
02977 
02978 
02979 class MonitorEnterMessage : public JavaMessage {
02980        jobject obj;
02981        jint* result;
02982 public:
02983        MonitorEnterMessage(jobject obj, jint* result)
02984        {
02985               this->obj = obj;
02986               this->result = result;
02987        }
02988 
02989        virtual void execute(JNIEnv* env)
02990        {
02991               *result = env->MonitorEnter(obj);
02992        }
02993 };
02994 
02995 NS_IMETHODIMP CSecureEnv::MonitorEnter(/*[in]*/  jobject obj,
02996                                         /*[out]*/ jint* result) 
02997 {
02998     if (mJavaEnv == NULL || result == NULL)
02999         return NS_ERROR_NULL_POINTER;
03000 
03001 #if PROXY_JNI_CALLS
03002        MonitorEnterMessage msg(obj, result);
03003        sendMessageToJava(&msg);
03004 #else
03005        *result = mJavaEnv->MonitorEnter(obj);
03006 #endif
03007 
03008     return NS_OK;
03009 }
03010 
03011 class MonitorExitMessage : public JavaMessage {
03012        jobject obj;
03013        jint* result;
03014 public:
03015        MonitorExitMessage(jobject obj, jint* result)
03016        {
03017               this->obj = obj;
03018               this->result = result;
03019        }
03020 
03021        virtual void execute(JNIEnv* env)
03022        {
03023               *result = env->MonitorExit(obj);
03024        }
03025 };
03026  
03027 NS_IMETHODIMP CSecureEnv::MonitorExit(/*[in]*/  jobject obj,
03028                                        /*[out]*/ jint* result)
03029 {
03030     if (mJavaEnv == NULL || result == NULL)
03031         return NS_ERROR_NULL_POINTER;
03032 
03033 #if PROXY_JNI_CALLS
03034        MonitorExitMessage msg(obj, result);
03035        sendMessageToJava(&msg);
03036 #else
03037        *result = mJavaEnv->MonitorExit(obj);
03038 #endif
03039 
03040     return NS_OK;
03041 }
03042 
03043 NS_IMETHODIMP CSecureEnv::GetJavaVM(/*[in]*/  JavaVM **vm,
03044                                      /*[out]*/ jint* result)
03045 {
03046     if (mJavaEnv == NULL || result == NULL)
03047         return NS_ERROR_NULL_POINTER;
03048 
03049     *result = mJavaEnv->GetJavaVM(vm);
03050 
03051     return NS_OK;
03052 }
03053 
03058 void CSecureEnv::messageLoop(JNIEnv* env, JavaMessage* msg, JavaMessageQueue* sendQueue, JavaMessageQueue* receiveQueue, Boolean busyWaiting)
03059 {
03060        // put the message in the send queue, and wait for a reply.
03061        sendQueue->putMessage(msg);
03062        sendQueue->notify();
03063        JavaMessage* replyMsg = receiveQueue->getMessage();
03064        for (;;) {
03065               // Fully synchronized approach.
03066               if (replyMsg != NULL) {
03067                      if (replyMsg == msg)
03068                             break;
03069                      // must be a message that needs executing.
03070                      replyMsg->execute(env);
03071                      sendQueue->putMessage(replyMsg);
03072                      sendQueue->notify();
03073                      // notify can cause a yield, so look again.
03074                      replyMsg = receiveQueue->getMessage();
03075                      if (replyMsg != NULL)
03076                             continue;
03077               }
03078               // when busy waiting, must give time to browser between timed waits.
03079               if (busyWaiting) {
03080                      receiveQueue->wait(1024);
03081                      replyMsg = receiveQueue->getMessage();
03082                      if (replyMsg != NULL)
03083                             continue;
03084                      // mSession->lock();
03085                      mThreadManager->Sleep();
03086                      // mSession->unlock();
03087               } else {
03088                      // wait for a message to arrive.
03089                      receiveQueue->wait();
03090               }
03091               replyMsg = receiveQueue->getMessage();
03092        }
03093 }
03094 
03095 void CSecureEnv::savePendingException(JNIEnv* env)
03096 {
03097     // first off, always restore the env to a known state.
03098     jthrowable pendingException = env->ExceptionOccurred();
03099     if (pendingException) {
03100 #if USE_LIVECONNECT_PROXY    
03101         env->ExceptionDescribe();
03102 #endif
03103         env->ExceptionClear();
03104         
03105         if (mPendingException)
03106             env->DeleteGlobalRef(mPendingException);
03107 
03108         mPendingException = (jthrowable) env->NewGlobalRef(pendingException);
03109         env->DeleteLocalRef(pendingException);
03110     }
03111 }
03112 
03113 jthrowable CSecureEnv::getPendingException(JNIEnv* env)
03114 {
03115     if (mPendingException)
03116         return (jthrowable) env->NewLocalRef(mPendingException);
03117     return NULL;
03118 }
03119 
03120 void CSecureEnv::clearPendingException(JNIEnv* env)
03121 {
03122     if (mPendingException) {
03123         env->DeleteGlobalRef(mPendingException);
03124         mPendingException = NULL;
03125     }
03126 }
03127 
03128 CSecureEnv* GetSecureJNI(JNIEnv* env, jobject thread)
03129 {
03130        CSecureEnv* secureJNI = NULL;
03131        
03132        jclass threadClass = env->GetObjectClass(thread);
03133        if (threadClass != NULL) {
03134               jfieldID fSecureEnvField = env->GetFieldID(threadClass, "fSecureEnv", "I");
03135               if (fSecureEnvField != NULL) {
03136                      secureJNI = (CSecureEnv*) env->GetIntField(thread, fSecureEnvField);
03137               } else {
03138                      env->ExceptionClear();
03139               }
03140               env->DeleteLocalRef(threadClass);
03141        }
03142        
03143        return secureJNI;
03144 }