Microsoft KB Archive/252661

= PRB: WFC-Based ActiveX Control Is Not Safe for Scripting =

Article ID: 252661

Article Last Modified on 10/16/2007

-

APPLIES TO


 * Microsoft Visual J++ 1.1 Standard Edition
 * Microsoft Visual J++ 6.0 Standard Edition
 * Microsoft Internet Explorer 5.0
 * Microsoft Internet Explorer 5.01
 * Microsoft Internet Explorer (Programming) 5.01 SP1
 * Microsoft Internet Explorer 5.5
 * Microsoft Software Development Kit for Java 1.51
 * Microsoft Software Development Kit for Java 3.2
 * Microsoft Software Development Kit 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:

MIDL objsafe.idl

 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:

http://msdn.microsoft.com/workshop/components/com /reference/ifaces/iobjectsafety/iobjectsafety.asp

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.</li> 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.</li>  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>

<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>

</li></ol>

<div class="moreinformation_section">

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.

<div class="references_section">