ActiveX in Firefox? You’re crazy!
December 28th, 2007Not that long ago a friend of mine and I were talking about the insecurities of Internet Explorer. Eventually the conservation turned to Firefox and how it is more secure. My friend stated the fact that ActiveX doesn’t work in Firefox, which makes it more secure. I laughed at this statement and my friend proceeded to rail me for smirking. He was so sure that ActiveX does not work in Firefox that he insulted me for saying otherwise. What my friend didn’t know is that awhile back I had figured out a way to make ActiveX work with Firefox.
At my first job back in 2004, my boss asked me if there was a way to get the label printing ActiveX to work in Firefox. We developed a website that users could upload label designs, define or upload data for the label design, and print the labels. He was concerned that a lot of clients were switching to Firefox because of all the security issues with IE 6 and the ActiveX doesn’t work in Firefox. I told him that I would do some research and that I would get back to him in a week.
I started searching the internet about ActiveX in Firefox and came up with no answers. At this point I asked myself; Well what does work in Firefox? I answered; Java works in Firefox. I remembered my studies of the JNI (Java Native Interface). The JNI allows developers to write code in other languages and use it in Java. This got the wheels turning and I began to layout my plan of action. I would create a wrapper for the ActiveX that I could call from the JRE (Java Runtime Environment). The wrapper code would simply call the ActiveX dll and pass any data along. I would then embed a Java applet in the web pages to call the wrapper code. This would in turn call the ActiveX and ta-da! ActiveX working in Firefox.
This isn’t just some unproven idea. I actually did it. The ActiveX was written in Delphi. So I wrote the wrapper code in Delphi as well. The wrapper code used the jni wrapper 2.7 for Delphi to interface the ActiveX with the JRE. As an example, below are snippets of the actual code.
Delphi ActiveX code:
function RetrieveData(const login: WideString; jobID: Integer): WideString; safecall;
Wrapper Delphi code:
function Java_ICfxWebEngine_RetrieveData(penv: PJNIEnv; obj: jclass; login: jstring; jobID: jint): jstring; stdcall;
begin
TJavaVM.SetThreadPenv(penv);
try
Result := createJString(StringReplace(engine.RetrieveData(JToDString(login), jobId), #10#13, ”, [rfReplaceAll]) + #0);
except on e:exception do MessageBox(0, PChar(e.Message), ‘Error Retrieving Data:’, MB_OK);
end;
end;
exports
Java_ICfxWebEngine_RetrieveData;
end.
Java code:
public class ICfxWebEngine
{
public static native String RetrieveData(String login, int jobID);
/**
JNI function to load the dll
*/
static {
System.loadLibrary( “CFXWebLibWrapper” );
}
}// end ICfxWebEngine class
JNI code (c++ header file):
/*
* Class: ICfxWebEngine
* Method: RetrieveData
* Signature: (Ljava/lang/String;I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_ICfxWebEngine_RetrieveData(JNIEnv *, jobject, jstring, jint);
Java Applet code:
public class WebApplet extends JApplet
{
private ICfxWebEngine engine;
private PrintPreview printPreview;
/**
*
*/
public ICfxWebEngine getActiveX()
{
// create the LabelsAnywhere activeX wrapper
// (interface dll between this java applet and the activeX)
engine = new ICfxWebEngine();
engine.Init();
return engine;
}// end getActiveX()
/**
@params login login name
@params jobID id of the job to retrieve data for
@return String - the retrieved xml data
*/
public String retrieveData(String login, String jobID)
{
engine = getActiveX();
return (engine.RetrieveData(login, (Integer.parseInt(jobID))));
}// end retrieveData()
}// end WebApplet class
The applet embedded in the web page calls ICfxWebEngine.RetrieveData(”userX”, 123456789);
and passes in the user login and jobID (a job is the label design with the associated data for it). This function calls the JNI code Java_IcfxWebEngine_RetrieveData(). This passes the data to the wrapper code function. Finally, the wrapper code calls createJString(engine.RetrieveData(JToDString(login), jobId)). This code calls the ActiveX RetrieveData function. Essentially the applet and wrapper code act as a pass thru from the web page to the ActiveX.
The .java.policy file in the JRE had to be modified to get the wrapper code, applet, and ActiveX to work. Also the wrapper dll had to be added to the JRE folder or exist in a folder in the CLASSPATH.
.java.policy file:
grant {
permission java.lang.RuntimePermission “loadLibrary.CFXWebLibWrapper”;
permission java.lang.RuntimePermission “loadLibrary.CfxWebLibWrapper”;
permission java.lang.RuntimePermission “loadLibrary.CFXWebLib”;
permission java.io.FilePermission “C:\\PROGRA~1\\JavaJRE15~1.0_0\\lib\\ext\\CfxWebLibWrapper.dll”, “read, execute”;
permission java.io.FilePermission “C:\\PROGRA~1\\JavaJRE15~1.0_0\\lib\\ext\\x86\\CfxWebLibWrapper.dll”, “read, execute”;
permission java.io.FilePermission “C:\\PROGRA~1\\Java\\JRE15~2.0_0\\lib\\ext\\CFXWebLibWrapper.dll”, “read, execute”;
permission java.io.FilePermission “C:\\PROGRA~1\\Java\\JRE15~2.0_0\\lib\\ext\\x86\\CFXWebLibWrapper.dll”, “read, execute”;
};
All that was left was to create an installer for the wrapper dll, JRE classes (in a jar file) and add the entries to the .java.policy file.
I presented all of this to my boss and he was very impressed. I created a prototype page where it allowed the user to login, upload some data, and print a specific label design. Everything worked perfectly but my boss didn’t want to spend the time and money to modify the web pages to add the applet to them.
Now this was a special case in that I had access to the source code for the ActiveX. This, however, is not a problem because ActiveX is a COM object. It must inherit from the IUnknown interface. This interface has a function called QueryInterface(). With this function you can determine all of the functions available to you in the ActiveX and all of the parameters for the functions (See http://en.wikipedia.org/wiki/Component_Object_Model for more information). So, with a little bit of coding, you can automatically create wrapper objects and the associated Java applet and JNI files to enable any ActiveX to work in Firefox. Now obviously you will need to add the applet to the web page and pass any data from the page to the applet…
















