++的博客

你看不见我,你看不见我。。
随笔 - 22, 文章 - 0, 评论 - 2, 引用 - 0
数据加载中……

用ATL编写标识为脚本安全的ActiveX控件

一半来说,ActiveX控件在WEB开发的时候要避免使用,如果实在无法避免,则需要注意几点:
1. ActiveX发布后一定要代码签名
2. 编写的时候要标记为脚本安全

下面是针对VS2005 ATL工程向导生成的工程,加入“脚本安全”的特性

修改生成的.h文件
#pragma once
#include 
"resource.h"       // 主符号

#include 
"Launch.h"
#include 
<vector>
#include 
<atlctl.h>


// CEduTaimentConsole

class ATL_NO_VTABLE CEduTaimentConsole : 
    
public CComObjectRootEx<CComSingleThreadModel>,
    
public CComCoClass<CEduTaimentConsole, &CLSID_EduTaimentConsole>,
    
public IDispatchImpl<IEduTaimentConsole, &IID_IEduTaimentConsole, &LIBID_LaunchLib, /*wMajor =*/ 1/*wMinor =*/ 0>,

    
// 加入IObjectSafetyImpl,实现IObjectSafety
    public IObjectSafetyImpl<CEduTaimentConsole, INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA> 
{
public:
    CEduTaimentConsole()
    
{
    }


DECLARE_REGISTRY_RESOURCEID(IDR_EDUTAIMENTCONSOLE)


BEGIN_COM_MAP(CEduTaimentConsole)
    
// 实现安全接口
    COM_INTERFACE_ENTRY(IObjectSafety)
    
    COM_INTERFACE_ENTRY(IEduTaimentConsole)
    COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// 加入到CATID_SafeForScripting 和 CATID_SafeForInitializing COM分组
BEGIN_CATEGORY_MAP(CEduTaimentConsole)
    IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
    IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
END_CATEGORY_MAP()


    DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct()
    
{
        
return S_OK;
    }

    
    
void FinalRelease() 
    
{
    }


public:

    STDMETHOD(ShowDesktop)(VARIANT_BOOL vbShow);
    STDMETHOD(EnableCtrlAltDel)(VARIANT_BOOL vbEnabled);
    STDMETHOD(EnableHotKey)(VARIANT_BOOL vbEnabled);
    STDMETHOD(ChangeDisplay)(VARIANT_BOOL vbChange);

    
// 加入这2个方法
    STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid,DWORD *pdwSupportedOptions,DWORD *pdwEnabledOptions);
    STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid,DWORD dwOptionSetMask,DWORD dwEnabledOptions);

    
static BOOL IsDesktopVisible(void);

    
static BOOL CALLBACK __EnumWindowsProc( HWND hwnd, LPARAM lParam);
    
static void __ShowApplications(BOOL bShow);
    
static void __ShowDesktop(BOOL bShow);
    
static BOOL __EnableHotKey(BOOL bEnabled);
    
static void __EnableCtrlAltDel(BOOL bEnabled);
}
;



OBJECT_ENTRY_AUTO(__uuidof(EduTaimentConsole), CEduTaimentConsole)

修改.cpp文件,加入的2个方法
STDMETHODIMP CEduTaimentConsole::GetInterfaceSafetyOptions(REFIID riid,
                                     DWORD 
*pdwSupportedOptions,
                                     DWORD 
*pdwEnabledOptions)
{
    ATLTRACE(_T(
"CObjectSafetyImpl::GetInterfaceSafetyOptions\n"));
    
if (!pdwSupportedOptions || !pdwEnabledOptions)
        
return E_FAIL;
    LPUNKNOWN pUnk;
    
if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) {
        
// Our object doesn't even support this interface.
        return E_NOINTERFACE;
    }
else{
        
// Cleanup after ourselves.
        pUnk->Release();
        pUnk 
= NULL;
    }

    
if (riid == IID_IDispatch) {
        
// IDispatch is an interface used for scripting. If your
        
// control supports other IDispatch or Dual interfaces, you
        
// may decide to add them here as well. Client wants to know
        
// if object is safe for scripting. Only indicate safe for
        
// scripting when the interface is safe.
        *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
        
*pdwEnabledOptions = m_dwCurrentSafety &
            INTERFACESAFE_FOR_UNTRUSTED_CALLER;
        
return S_OK;
    }
else if ((riid == IID_IPersistStreamInit) ||
        (riid 
== IID_IPersistStorage)) {
            
// IID_IPersistStreamInit and IID_IPersistStorage are
            
// interfaces used for Initialization. If your control
            
// supports other Persistence interfaces, you may decide to
            
// add them here as well. Client wants to know if object is
            
// safe for initializing. Only indicate safe for initializing
            
// when the interface is safe.
            *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
            
*pdwEnabledOptions = m_dwCurrentSafety &
                INTERFACESAFE_FOR_UNTRUSTED_DATA;
            
return S_OK;
    }
else{
        
// We are saying that no other interfaces in this control are
        
// safe for initializing or scripting.
        *pdwSupportedOptions = 0;
        
*pdwEnabledOptions = 0;
        
return E_FAIL;
    }

}


STDMETHODIMP CEduTaimentConsole::SetInterfaceSafetyOptions(REFIID riid,
                                     DWORD dwOptionSetMask,
                                     DWORD dwEnabledOptions)
{
    ATLTRACE(_T(
"CObjectSafetyImpl::SetInterfaceSafetyOptions\n"));
    
if (!dwOptionSetMask && !dwEnabledOptions) return E_FAIL;
    LPUNKNOWN pUnk;
    
if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) {
        
// Our object doesn't even support this interface.
        return E_NOINTERFACE;
    }
else{
        
// Cleanup after ourselves.
        pUnk->Release();
        pUnk 
= NULL;
    }

    
// Store our current safety level to return in
    
// GetInterfaceSafetyOptions
    m_dwCurrentSafety |= dwEnabledOptions & dwOptionSetMask;
    
if ((riid == IID_IDispatch) &&
        (m_dwCurrentSafety 
& INTERFACESAFE_FOR_UNTRUSTED_CALLER)) {
            
// Client wants us to disable any functionality that would
            
// make the control unsafe for scripting. The same applies to
            
// any other IDispatch or Dual interfaces your control may
            
// support. Because our control is safe for scripting by
            
// default we just return S_OK.
            return S_OK;
    }
else if (((riid == IID_IPersistStreamInit) ||
        (riid 
== IID_IPersistStorage)) &&
        (m_dwCurrentSafety 
& INTERFACESAFE_FOR_UNTRUSTED_DATA)) {
            
// Client wants us to make the control safe for initializing
            
// from persistent data. For these interfaces, this control
            
// is safe so we return S_OK. For Any interfaces that are not
            
// safe, we would return E_FAIL.
            return S_OK;
    }
else{
        
// This control doesn't allow Initialization or Scripting
        
// from any other interfaces so return E_FAIL.
        return E_FAIL;
    }

}


posted on 2008-06-19 09:57 Jerry.Wang 阅读(1621) 评论(0)  编辑 收藏 引用 所属分类: 开发