PRB: WFC-Based ActiveX Control Is Not Safe for Scripting (252661)
The information in this article applies to:
- Microsoft Visual J++ 1.1
- Microsoft Visual J++ 6.0
- Microsoft Internet Explorer (Programming) 5
- Microsoft Internet Explorer (Programming) 5.01
- Microsoft Internet Explorer (Programming) 5.01 SP1
- Microsoft Internet Explorer (Programming) 5.5
- Microsoft SDK for Java 1.51
- Microsoft SDK for Java 3.2
- Microsoft SDK for Java 4.0
This article was previously published under Q252661 SYMPTOMS
If you use Microsoft Windows Foundation Classes for Java (WFC) to create an ActiveX control, you may receive the following error message (or similar) when you host the control from Internet Explorer 5:
This page contains controls that may not be safe -- and the controls are not made available to script code, or not loaded on the page at all.
CAUSE
This problem occurs because, by default, WFC-based ActiveX controls are not marked as safe for scripting, and Internet Explorer 5 is configured to disable scripting to an ActiveX control that is not marked safe for scripting.
RESOLUTION
To programmatically mark an ActiveX control as safe for scripting, you need to implement the IObjectSafety Component Object Model (COM) interface as follows:
- Generate the following Objsafe.idl file that creates a library for IObjectSafety:
//+---------------------------------------------------------------------------
//
// Copyright 1996-1997 Microsoft Corporation. All Rights Reserved.
//
// Contents: Object Safety Interfaces (should come from ObjSafe.idl)
//
//----------------------------------------------------------------------------
[
uuid(58357B30-FCF0-11d2-9AFA-0008C76BD28A),
helpstring("IObjectSafety Type Library")
]
library ObjSafe
{
importlib("StdOle2.Tlb");
[
object,
uuid(CB5BDC81-93C1-11cf-8F20-00805F2CD064),
pointer_default(unique)
]
interface IObjectSafety : IUnknown
{
HRESULT GetInterfaceSafetyOptions(
[in] REFIID riid, // Interface that we want options for
[out] DWORD * pdwSupportedOptions, // Options meaningful on this interface
[out] DWORD * pdwEnabledOptions); // Current option values on this interface
HRESULT SetInterfaceSafetyOptions(
[in] REFIID riid, // Interface to set options for
[in] DWORD dwOptionSetMask, // Options to change
[in] DWORD dwEnabledOptions); // New option values
}
}
- At a command prompt, type the following command to create a type library (.tlb) file:
- In Visual J++ 6.0, create a WFC control project.
- Create a wrapper class for the Objsafe.tlb file that you created in step 2. To do this, click Project.Add COM Wrapper, and then click Objsafe.tlb.
- Implement the IObjectSafety interface methods, as listed in the following Microsoft Web Workshop article:
The following code sample illustrates how to implement IObjectSafety in Java:
import com.ms.wfc.core.*;
import com.ms.wfc.ui.*;
import objsafe.*;
/**
* This class is a visual component. The entry point for class execution
* is the constructor.
*
* This class can be used as an ActiveX control.
* Select the check box for this class on the Project Properties
* COM Classes tab, or remove the // from the next line.
//*@com.register ( clsid=04FF1C46-3F64-4055-8CDD-0A46A7177B77,
typelib=5D3EA1DE-AC49-4ADF-9FD3-22E273DF1B24 )
*@com.register ( clsid=5B255D39-21F4-421B-84E2-F12A6598B1D4,
typelib=1A4FF1B3-6FBA-4FB0-889E-369947A5A72D )
*/
public class Control1 extends UserControl implements IObjectSafety
{
public Control1()
{
// Required for Visual J++ Form Designer support:
initForm();
// TO DO: Add any constructor code after initForm call.
}
public String TestSafetyMethod()
{
return "Passed!";
}
//Implement IObjectSafety:
public void GetInterfaceSafetyOptions(com.ms.com._Guid riid, int[]
pdwSupportedOptions, int[] pdwEnabledOptions)
{
pdwSupportedOptions[0] = INTERFACE_SAFE_FOR_UNTRUSTED_CALLER |
INTERFACE_SAFE_FOR_UNTRUSTED_DATA;
if (riid != null)
{
com.ms.wfc.util.Debug.println("riid: " + riid.toString());
if (riid.equals(IID_IDispatch))
{
pdwEnabledOptions[0] = 0;
if (SAFE_FOR_SCRIPTING) pdwEnabledOptions[0] =
INTERFACE_SAFE_FOR_UNTRUSTED_CALLER;
}
else if ( riid.equals(IID_IPersistPropertyBag)
|| riid.equals(IID_IPersistStorage)
|| riid.equals(IID_IPersistStream) )
{
pdwEnabledOptions[0] = 0;
if (SAFE_FOR_INITIALIZATION) pdwEnabledOptions[0] =
INTERFACE_SAFE_FOR_UNTRUSTED_DATA;
}
else throw new com.ms.com.ComFailException(E_NOINTERFACE);
}
}
public void SetInterfaceSafetyOptions(com.ms.com._Guid riid, int
dwOptionSetMask, int dwEnabledOptions)
{
if (riid != null)
{
com.ms.wfc.util.Debug.println("riid: " + riid.toString());
if (riid.equals(IID_IDispatch))
{
if ((dwEnabledOptions & dwOptionSetMask) !=
INTERFACE_SAFE_FOR_UNTRUSTED_CALLER)
{
throw new com.ms.com.ComFailException(E_FAIL);
}
else
{
if (SAFE_FOR_SCRIPTING == false)
{
throw new com.ms.com.ComFailException(E_FAIL);
}
}
}
else if ( riid.equals(IID_IPersistPropertyBag)
|| riid.equals(IID_IPersistStorage)
|| riid.equals(IID_IPersistStreamInit)
|| riid.equals(IID_IPersistStream) )
{
if ((dwEnabledOptions & dwOptionSetMask)
!=INTERFACE_SAFE_FOR_UNTRUSTED_DATA)
{
throw new com.ms.com.ComFailException(E_FAIL);
}
else
{
if (SAFE_FOR_INITIALIZATION == false)
{
throw new com.ms.com.ComFailException(E_FAIL);
}
}
}
else throw new com.ms.com.ComFailException(E_NOINTERFACE);
}
}
//GUIDs for IObjectSafety methods:
public static final com.ms.com._Guid IID_IDispatch = new
com.ms.com._Guid("{00020400-0000-0000-C000-000000000046}");
public static final com.ms.com._Guid IID_IPersistStorage = new
com.ms.com._Guid("{0000010A-0000-0000-C000-000000000046}");
public static final com.ms.com._Guid IID_IPersistStream = new
com.ms.com._Guid("{00000109-0000-0000-C000-000000000046}");
public static final com.ms.com._Guid IID_IPersistPropertyBag = new
com.ms.com._Guid("{37D84F60-42CB-11CE-8135-00AA004BB851}");
public static final com.ms.com._Guid IID_IPersistStreamInit = new
com.ms.com._Guid("{7FD52380-4E07-101B-AE2D-08002B2EC713}");
//Constants for IObjectSafety methods:
public static final int INTERFACE_SAFE_FOR_UNTRUSTED_CALLER = 0x1;
public static final int INTERFACE_SAFE_FOR_UNTRUSTED_DATA = 0x2;
public static final int E_NOINTERFACE = 0x80004002;
public static final int E_FAIL = 0x80004005;
//IObjectSafety settings:
public static final boolean SAFE_FOR_SCRIPTING = true;
public static final boolean SAFE_FOR_INITIALIZATION = true;
/**
* NOTE: The Visual J++ Form Designer requires the following code.
* You can use the Form editor to modify the code; however, do
* not use the code editor to modify the code.
*/
Container components = new Container();
Label label1 = new Label();
private void initForm()
{
this.setSize(new Point(164, 71));
this.setText("Control1");
label1.setLocation(new Point(32, 24));
label1.setSize(new Point(100, 16));
label1.setTabIndex(0);
label1.setTabStop(false);
label1.setText("IObjectSafety Rules!");
this.setNewControls(new Control[] {label1});
}
// NOTE: End of Form Designer support code.
public static class ClassInfo extends UserControl.ClassInfo
{
// TO DO: Add your property and event information here.
}
}
- Build the Control Project.
- Follow the steps in the Microsoft Knowledge Base article 247315 to package the control as a COM dynamic-link library (DLL) file, and then package it into a .cab file to access the control from scripting.
- Create a new HTML file that begins the installation process when it is accessed.
Create the HTML file in the same folder as the generated .cab file. The following sample assumes that your .cab file is named Cabinet1.cab. Replace the sample ClassID with the ClassID that is listed in the "@com.register" tag within the first block comment in Control1.java:
<HTML>
<script language=javascript for=window event=onload>
<!--
alert(Control1.TestSafetyMethod());
//-->
</script>
<BODY>
<OBJECT classid=clsid:99999999-9999-9999-9999-999999999999 id=Control1 VIEWASTEXT
codeBase="Cabinet1.CAB#version=1,1,1,1">
</OBJECT>
You should see a MessageBox saying "Passed".
</BODY>
</HTML>
MORE INFORMATION
You should mark your controls as safe for scripting only if all of the public methods that the controls expose do not perform any operations that are outside of the sandbox, that is, anything that could compromise the security, in particular accessing disk or network resources or file enumerations.
REFERENCESFor additional information, click the article number below
to view the article in the Microsoft Knowledge Base:
182598 HOWTO: Implement IObjectSafety in Visual Basic Controls
For more information about safe initialization and scripting of ActiveX controls, see the following MSDN article:
For more information about the IObjectSafety extensions, see the following MSDN article:
For more information about the IObjectSafety interface, see the following MSDN article:
For support information about Visual J++ and the SDK for Java, visit the following Microsoft Web site:
Modification Type: | Major | Last Reviewed: | 6/14/2006 |
---|
Keywords: | kbCtrl kbDownload kbJava kbprb kbSecurity kbWFC KB252661 |
---|
|