VB控件實現IObjectSafety安全接口(zt)
本文敘述瞭如何在VB中實現控件的IobjectSafety接口,以標誌該控件是腳本安全和初始化安全的。
VB控件默認的處理方式是在註冊表中註冊組件類來標識其安全性,
但實現IobjectSafety接口是更好的方法。
本文包括了實現過程中所需的所有代碼。
1、將以下文本複製到記事本, 並作爲 objsafe.odl 項目文件夾以保存文件:
[
uuid(C67830E0-D11D-11cf-BD80-00AA00575603),
helpstring("VB IObjectSafety Interface"),
version(1.0)
]
library
IObjectSafetyTLB
{
importlib("stdole2.tlb");
[
uuid(CB5BDC81-93C1-11cf-8F20-00805F2CD064),
helpstring("IObjectSafety Interface"),
odl
]
interface
IObjectSafety:IUnknown {
[helpstring("GetInterfaceSafetyOptions")]
HRESULT
GetInterfaceSafetyOptions(
[in] long
riid,
[in] long
*pdwSupportedOptions,
[in] long *pdwEnabledOptions);
[helpstring("SetInterfaceSafetyOptions")]
HRESULT
SetInterfaceSafetyOptions(
[in] long
riid,
[in]
long dwOptionsSetMask,
[in] long
dwEnabledOptions);
}
}
---------------------------------------------------------------------
2、在命令提示符處,
使用 CD < 路徑 > 命令移到項目文件夾, 然後鍵入以下命令以生成 .tlb 文件:
MKTYPLIB objsafe.odl /tlb
objsafe.tlb
---------------------------------------------------------------------
3、在VB中新建一個ActiveX
Control
項目。修改屬性,把項目命名爲IobjSafety,控件命名爲DemoCtl。在控件上放置一個按鈕,命名爲cmdTest,在它的Click事件中加入一句代碼
MsgBox "Test"
---------------------------------------------------------------------
4、在
項目 菜單上, 單擊 引用 , 瀏覽並添加
Objsafe.tlb
---------------------------------------------------------------------
5、項目添加一個新模塊並命名模塊
basSafeCtl,添加一下代碼
Option Explicit
Public Const IID_IDispatch =
"{00020400-0000-0000-C000-000000000046}"
Public Const
IID_IPersistStorage = _
"{0000010A-0000-0000-C000-000000000046}"
Public Const
IID_IPersistStream = _
"{00000109-0000-0000-C000-000000000046}"
Public Const
IID_IPersistPropertyBag = _
"{37D84F60-42CB-11CE-8135-00AA004BB851}"
Public Const INTERFACESAFE_FOR_UNTRUSTED_CALLER =
&H1
Public Const INTERFACESAFE_FOR_UNTRUSTED_DATA =
&H2
Public Const E_NOINTERFACE =
&H80004002
Public Const E_FAIL =
&H80004005
Public Const MAX_GUIDLEN = 40
Public Declare Sub CopyMemory Lib "kernel32" Alias
"RtlMoveMemory" _
(pDest As Any, pSource As Any, ByVal
ByteLen As Long)
Public Declare Function StringFromGUID2
Lib "ole32.dll" (rguid As _
Any, ByVal lpstrClsId As
Long, ByVal cbMax As Integer) As Long
Public Type udtGUID
Data1 As
Long
Data2 As Integer
Data3 As Integer
Data4(7) As
Byte
End Type
Public m_fSafeForScripting As
Boolean
Public m_fSafeForInitializing As Boolean
Sub Main()
m_fSafeForScripting
= True
m_fSafeForInitializing =
True
End
Sub
---------------------------------------------------------------------
6、在工程屬性中把啓動對象改成Sub
Main確保上述代碼會被執行。m_fSafeForScripting
和m_fSafeForInitializing兩件變量的值分別指定了腳本安全和初始化安全取值。
8、打開控件的代碼窗口。 將下列行的代碼添加到聲明部分
(OptionExplicit 後):
Implements
IObjectSafety
---------------------------------------------------------------------
9、將下面兩個過程複製到控件代碼:
Private Sub IObjectSafety_GetInterfaceSafetyOptions(ByVal riid As
_
Long, pdwSupportedOptions As Long, pdwEnabledOptions As
Long)
Dim Rc As
Long
Dim rClsId As
udtGUID
Dim IID As
String
Dim bIID() As Byte
pdwSupportedOptions =
INTERFACESAFE_FOR_UNTRUSTED_CALLER Or
_
INTERFACESAFE_FOR_UNTRUSTED_DATA
If (riid <> 0)
Then
CopyMemory rClsId, ByVal riid,
Len(rClsId)
bIID = String$(MAX_GUIDLEN,
0)
Rc = StringFromGUID2(rClsId, VarPtr(bIID(0)),
MAX_GUIDLEN)
Rc = InStr(1, bIID, vbNullChar) -
1
IID = Left$(UCase(bIID), Rc)
Select Case
IID
Case
IID_IDispatch
pdwEnabledOptions =
IIf(m_fSafeForScripting, _
INTERFACESAFE_FOR_UNTRUSTED_CALLER, 0)
Exit Sub
Case IID_IPersistStorage,
IID_IPersistStream, _
IID_IPersistPropertyBag
pdwEnabledOptions
= IIf(m_fSafeForInitializing, _
INTERFACESAFE_FOR_UNTRUSTED_DATA, 0)
Exit
Sub
Case
Else
Err.Raise
E_NOINTERFACE
Exit
Sub
End Select
End
If
End Sub
Private Sub IObjectSafety_SetInterfaceSafetyOptions(ByVal
riid As _
Long, ByVal dwOptionsSetMask As Long, ByVal
dwEnabledOptions As Long)
Dim
Rc As Long
Dim
rClsId As udtGUID
Dim
IID As String
Dim
bIID() As Byte
If (riid <> 0)
Then
CopyMemory rClsId, ByVal riid,
Len(rClsId)
bIID = String$(MAX_GUIDLEN,
0)
Rc = StringFromGUID2(rClsId, VarPtr(bIID(0)),
MAX_GUIDLEN)
Rc = InStr(1, bIID, vbNullChar) -
1
IID = Left$(UCase(bIID), Rc)
Select Case
IID
Case
IID_IDispatch
If ((dwEnabledOptions And
dwOptionsSetMask) <> _
INTERFACESAFE_FOR_UNTRUSTED_CALLER)
Then
Err.Raise
E_FAIL
Exit
Sub
Else
If Not m_fSafeForScripting
Then
Err.Raise
E_FAIL
End
If
Exit
Sub
End If
Case IID_IPersistStorage, IID_IPersistStream,
_
IID_IPersistPropertyBag
If
((dwEnabledOptions And dwOptionsSetMask) <>
_
INTERFACESAFE_FOR_UNTRUSTED_DATA)
Then
Err.Raise
E_FAIL
Exit
Sub
Else
If Not m_fSafeForInitializing
Then
Err.Raise
E_FAIL
End
If
Exit
Sub
End If
Case
Else
Err.Raise
E_NOINTERFACE
Exit
Sub
End Select
End
If
End
Sub
---------------------------------------------------------------------
10、在
文件 菜單上, 保存您的項目和文件。 生成 OCX 文件從項目。 現在您控件實現 IObjectSafety 接口。 要測試, 在一個 .htm
文件中插入控件。
相關連接:
http://topic.csdn.net/t/20050104/23/3699426.html
原理
IObjectSafety 是一個接口,它可將其功能顯露給 Internet Explorer 的“設置腳本安全性”和“設置初始化安全性”安全特性。對具有支持未受託客戶(或那些不能預料其特定功能的,或不能確保安全使用的客戶)接口的對象,例如 腳本,應當實現 IObjectSafety 接口。該接口允許您指定對象的哪一部分需要保護而不被使用。---------------------------------------------------------------------
使用 IObjectSafety 可以將對象及其組成部分標記爲以下三類:
1、對未受託的 Automation 客戶和腳本設置 Automation 安全性
2、對未受託數據設置初始化安全性
3、對未受託腳本設置運行安全性
---------------------------------------------------------------------
可以爲您的對象考慮三種方案:
1、 對象的所有屬性和方法總是設置腳本安全性的。在該方案中,您可以通過不在 IObjectSafety_SetInterfaceSafetyOptions 接口方法中返回錯誤來通知客戶您的對象設置了腳本安全性。這樣就能成功地創建和運行您的對象了。
2、對象永不設置腳本安全性。在這種情況下,您可以通過在 IObjectSafety_SetInterfaceSafetyOptions 接口方法中返回一個錯誤,E_Fail 來通知客戶您的對象不安全。這樣就防止了客戶通過腳本來訪問任何方法或屬性了
3、對象上的部分屬性和方法,但不是全部,未設置腳本安全性。在這種情況下,您可以通知客戶整個對象都不安全,也可以通知客戶您的對象是安全的,但禁用不安全的屬性和方法。
--------------------------------------------------------------------
TLB用於定義接口.
Implements 在VB中繼承並實現定義的 接口.
IObjectSafety_GetInterfaceSafetyOptions
IObjectSafety_SetInterfaceSafetyOptions
是定義IObjectSafety的一個InterfaceSafetyOptions屬性.要做的動作.
--------------------------------------------------------------------
[
uuid(C67830E0-D11D-11cf-BD80-00AA00575603),
helpstring("VB IObjectSafety Interface"),
version(1.0)
]
這是接口定義語言(IDL:Interface Definition Language),C67830E0-D11D-11cf-BD80-00AA00575603不可以任意寫,它代表了IObjectSafety這個 接口,改了別人就找不到它了,如果創建一個新的類或接口,則可以任意寫,就是一組16進制數,但一般都用GUIDGEN.EXE生成,可以保證不重複